home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 6 / CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso / cucd / prog / gnu-c / src / gcc-2.7.0-amiga / config / sparc / sparc.md < prev    next >
Text File  |  1995-06-15  |  183KB  |  5,843 lines

  1. ;;- Machine description for SPARC chip for GNU C compiler
  2. ;;  Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
  3. ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
  4. ;;  64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
  5. ;;  at Cygnus Support.
  6.  
  7. ;; This file is part of GNU CC.
  8.  
  9. ;; GNU CC is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; GNU CC is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU CC; see the file COPYING.  If not, write to
  21. ;; the Free Software Foundation, 59 Temple Place - Suite 330,
  22. ;; Boston, MA 02111-1307, USA.
  23.  
  24. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  25.  
  26. ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
  27. ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
  28. ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
  29. ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
  30. ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
  31.  
  32. ;; Architecture type.  Arch32bit includes v7, sparclite, v8.
  33.  
  34. (define_attr "arch" "arch32bit,arch64bit"
  35.   (const (symbol_ref "sparc_arch_type")))
  36.  
  37. ;; CPU type. This is only used for instruction scheduling
  38. (define_attr "cpu" "cypress,supersparc"
  39.  (const
  40.   (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")]
  41.     (const_string "cypress"))))
  42.  
  43. ;; Insn type.  Used to default other attribute values.
  44.  
  45. ;; type "unary" insns have one input operand (1) and one output operand (0)
  46. ;; type "binary" insns have two input operands (1,2) and one output (0)
  47. ;; type "compare" insns have one or two input operands (0,1) and no output
  48. ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
  49.  
  50. (define_attr "type"
  51.   "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
  52.   (const_string "binary"))
  53.  
  54. ;; Set true if insn uses call-clobbered intermediate register.
  55. (define_attr "use_clobbered" "false,true"
  56.   (if_then_else (and (eq_attr "type" "address")
  57.              (match_operand 0 "clobbered_register" ""))
  58.          (const_string "true")
  59.         (const_string "false")))
  60.  
  61. ;; Length (in # of insns).
  62. (define_attr "length" ""
  63.   (cond [(eq_attr "type" "load,fpload")
  64.      (if_then_else (match_operand 1 "symbolic_memory_operand" "")
  65.                (const_int 2) (const_int 1))
  66.  
  67.      (eq_attr "type" "store,fpstore")
  68.      (if_then_else (match_operand 0 "symbolic_memory_operand" "")
  69.                (const_int 2) (const_int 1))
  70.  
  71.      (eq_attr "type" "address") (const_int 2)
  72.  
  73.      (eq_attr "type" "binary")
  74.      (if_then_else (ior (match_operand 2 "arith_operand" "")
  75.                 (match_operand 2 "arith_double_operand" ""))
  76.                (const_int 1) (const_int 3))
  77.  
  78.      (eq_attr "type" "multi") (const_int 2)
  79.  
  80.      (eq_attr "type" "move,unary")
  81.      (if_then_else (ior (match_operand 1 "arith_operand" "")
  82.                 (match_operand 1 "arith_double_operand" ""))
  83.                (const_int 1) (const_int 2))]
  84.  
  85.     (const_int 1)))
  86.  
  87. (define_asm_attributes
  88.   [(set_attr "length" "1")
  89.    (set_attr "type" "multi")])
  90.  
  91. ;; Attributes for instruction and branch scheduling
  92.  
  93. (define_attr "in_call_delay" "false,true"
  94.   (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
  95.          (const_string "false")
  96.      (eq_attr "type" "load,fpload,store,fpstore")
  97.          (if_then_else (eq_attr "length" "1")
  98.                   (const_string "true")
  99.                   (const_string "false"))
  100.      (eq_attr "type" "address")
  101.          (if_then_else (eq_attr "use_clobbered" "false")
  102.                   (const_string "true")
  103.                   (const_string "false"))]
  104.     (if_then_else (eq_attr "length" "1")
  105.               (const_string "true")
  106.               (const_string "false"))))
  107.  
  108. (define_delay (eq_attr "type" "call")
  109.   [(eq_attr "in_call_delay" "true") (nil) (nil)])
  110.  
  111. ;; ??? Should implement the notion of predelay slots for floating point
  112. ;; branches.  This would allow us to remove the nop always inserted before
  113. ;; a floating point branch.
  114.  
  115. ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
  116. ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
  117. ;; This is because doing so will add several pipeline stalls to the path
  118. ;; that the load/store did not come from.  Unfortunately, there is no way
  119. ;; to prevent fill_eager_delay_slots from using load/store without completely
  120. ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
  121. ;; because it prevents us from moving back the final store of inner loops.
  122.  
  123. (define_attr "in_branch_delay" "false,true"
  124.   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
  125.              (eq_attr "length" "1"))
  126.         (const_string "true")
  127.         (const_string "false")))
  128.  
  129. (define_attr "in_uncond_branch_delay" "false,true"
  130.   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
  131.              (eq_attr "length" "1"))
  132.         (const_string "true")
  133.         (const_string "false")))
  134.  
  135. (define_attr "in_annul_branch_delay" "false,true"
  136.   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
  137.              (eq_attr "length" "1"))
  138.         (const_string "true")
  139.         (const_string "false")))
  140.  
  141. (define_delay (eq_attr "type" "branch")
  142.   [(eq_attr "in_branch_delay" "true")
  143.    (nil) (eq_attr "in_annul_branch_delay" "true")])
  144.  
  145. (define_delay (eq_attr "type" "uncond_branch")
  146.   [(eq_attr "in_uncond_branch_delay" "true")
  147.    (nil) (nil)])
  148.    
  149. ;; Function units of the SPARC
  150.  
  151. ;; (define_function_unit {name} {num-units} {n-users} {test}
  152. ;;                       {ready-delay} {issue-delay} [{conflict-list}])
  153.  
  154. ;; The integer ALU.
  155. ;; (Noted only for documentation; units that take one cycle do not need to
  156. ;; be specified.)
  157.  
  158. ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
  159. ;; the inputs.
  160.  
  161. ;; (define_function_unit "alu" 1 0
  162. ;;  (eq_attr "type" "unary,binary,move,address") 1 0)
  163.  
  164. ;; ---- cypress CY7C602 scheduling:
  165. ;; Memory with load-delay of 1 (i.e., 2 cycle load).
  166. (define_function_unit "memory" 1 0 
  167.   (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2)
  168.  
  169. ;; SPARC has two floating-point units: the FP ALU,
  170. ;; and the FP MUL/DIV/SQRT unit.
  171. ;; Instruction timings on the CY7C602 are as follows
  172. ;; FABSs    4
  173. ;; FADDs/d    5/5
  174. ;; FCMPs/d    4/4
  175. ;; FDIVs/d    23/37
  176. ;; FMOVs    4
  177. ;; FMULs/d    5/7
  178. ;; FNEGs    4
  179. ;; FSQRTs/d    34/63
  180. ;; FSUBs/d    5/5
  181. ;; FdTOi/s    5/5
  182. ;; FsTOi/d    5/5
  183. ;; FiTOs/d    9/5
  184.  
  185. ;; The CY7C602 can only support 2 fp isnsn simultaneously.
  186. ;; More insns cause the chip to stall.
  187.  
  188. (define_function_unit "fp_alu" 1 0
  189.   (and (eq_attr "type" "fp")            (eq_attr "cpu" "cypress")) 5 5)
  190. (define_function_unit "fp_mds" 1 0
  191.   (and (eq_attr "type" "fpmul")         (eq_attr "cpu" "cypress")) 7 7)
  192. (define_function_unit "fp_mds" 1 0
  193.   (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)
  194. (define_function_unit "fp_mds" 1 0
  195.   (and (eq_attr "type" "fpsqrt")        (eq_attr "cpu" "cypress")) 63 63)
  196.  
  197. ;; ----- The TMS390Z55 scheduling
  198. ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume
  199. ;; three insns/cycle, and hence multiply all costs by three.
  200. ;; Combinations up to two integer, one ld/st, one fp.
  201. ;; Memory delivers its result in one cycle to IU, zero cycles to FP
  202. (define_function_unit "memory" 1 0
  203.   (and (eq_attr "type" "load")          (eq_attr "cpu" "supersparc")) 3 3)
  204. (define_function_unit "memory" 1 0
  205.   (and (eq_attr "type" "fpload")        (eq_attr "cpu" "supersparc")) 1 3)
  206. ;; at least one in three instructions can be a mem opt.
  207. (define_function_unit "memory" 1 0
  208.   (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3)
  209. ;; at least one in three instructions can be a shift op.
  210. (define_function_unit "shift" 1 0
  211.   (and (eq_attr "type" "shift")         (eq_attr "cpu" "supersparc")) 1 3)
  212.  
  213. ;; There are only two write ports to the integer register file
  214. ;; A store also uses a write port
  215. (define_function_unit "iwport" 2 0
  216.   (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3)
  217.  
  218. ;; Timings; throughput/latency
  219. ;; FADD     1/3    add/sub, format conv, compar, abs, neg
  220. ;; FMUL     1/3
  221. ;; FDIVs    4/6
  222. ;; FDIVd    7/9
  223. ;; FSQRTs   6/8
  224. ;; FSQRTd  10/12
  225. ;; IMUL     4/4
  226.  
  227. (define_function_unit "fp_alu" 1 0
  228.   (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)
  229. (define_function_unit "fp_mds" 1 0
  230.   (and (eq_attr "type" "fpmul")    (eq_attr "cpu" "supersparc")) 9 3)
  231. (define_function_unit "fp_mds" 1 0
  232.   (and (eq_attr "type" "fpdivs")   (eq_attr "cpu" "supersparc")) 18 12)
  233. (define_function_unit "fp_mds" 1 0
  234.   (and (eq_attr "type" "fpdivd")   (eq_attr "cpu" "supersparc")) 27 21)
  235. (define_function_unit "fp_mds" 1 0
  236.   (and (eq_attr "type" "fpsqrt")   (eq_attr "cpu" "supersparc")) 36 30)
  237. (define_function_unit "fp_mds" 1 0
  238.   (and (eq_attr "type" "imul")     (eq_attr "cpu" "supersparc")) 12 12)
  239.  
  240. ;; Compare instructions.
  241. ;; This controls RTL generation and register allocation.
  242.  
  243. ;; We generate RTL for comparisons and branches by having the cmpxx 
  244. ;; patterns store away the operands.  Then, the scc and bcc patterns
  245. ;; emit RTL for both the compare and the branch.
  246. ;;
  247. ;; We do this because we want to generate different code for an sne and
  248. ;; seq insn.  In those cases, if the second operand of the compare is not
  249. ;; const0_rtx, we want to compute the xor of the two operands and test
  250. ;; it against zero.
  251. ;;
  252. ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
  253. ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
  254. ;; insns that actually require more than one machine instruction.
  255.  
  256. ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  257.  
  258. (define_expand "cmpsi"
  259.   [(set (reg:CC 0)
  260.     (compare:CC (match_operand:SI 0 "register_operand" "")
  261.             (match_operand:SI 1 "arith_operand" "")))]
  262.   ""
  263.   "
  264. {
  265.   sparc_compare_op0 = operands[0];
  266.   sparc_compare_op1 = operands[1];
  267.   DONE;
  268. }")
  269.  
  270. (define_expand "cmpdi"
  271.   [(set (reg:CCX 0)
  272.     (compare:CCX (match_operand:DI 0 "register_operand" "")
  273.              (match_operand:DI 1 "arith_double_operand" "")))]
  274.   "TARGET_V9"
  275.   "
  276. {
  277.   sparc_compare_op0 = operands[0];
  278.   sparc_compare_op1 = operands[1];
  279.   DONE;
  280. }")
  281.  
  282. (define_expand "cmpsf"
  283.   [(set (reg:CCFP 0)
  284.     (compare:CCFP (match_operand:SF 0 "register_operand" "")
  285.               (match_operand:SF 1 "register_operand" "")))]
  286.   "TARGET_FPU"
  287.   "
  288. {
  289.   sparc_compare_op0 = operands[0];
  290.   sparc_compare_op1 = operands[1];
  291.   DONE;
  292. }")
  293.  
  294. (define_expand "cmpdf"
  295.   [(set (reg:CCFP 0)
  296.     (compare:CCFP (match_operand:DF 0 "register_operand" "")
  297.               (match_operand:DF 1 "register_operand" "")))]
  298.   "TARGET_FPU"
  299.   "
  300. {
  301.   sparc_compare_op0 = operands[0];
  302.   sparc_compare_op1 = operands[1];
  303.   DONE;
  304. }")
  305.  
  306. (define_expand "cmptf"
  307.   [(set (reg:CCFP 0)
  308.     (compare:CCFP (match_operand:TF 0 "register_operand" "")
  309.               (match_operand:TF 1 "register_operand" "")))]
  310.   "TARGET_FPU"
  311.   "
  312. {
  313.   sparc_compare_op0 = operands[0];
  314.   sparc_compare_op1 = operands[1];
  315.   DONE;
  316. }")
  317.  
  318. ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
  319. ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
  320. ;; the same code as v8 (the addx/subx method has more applications).  The
  321. ;; exception to this is "reg != 0" which can be done in one instruction on v9
  322. ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
  323. ;; branches.
  324.  
  325. ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
  326. ;; generate addcc/subcc instructions.
  327.  
  328. (define_expand "seqsi_special"
  329.   [(set (match_dup 3)
  330.     (xor:SI (match_operand:SI 1 "register_operand" "")
  331.         (match_operand:SI 2 "register_operand" "")))
  332.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  333.            (eq:SI (match_dup 3) (const_int 0)))
  334.           (clobber (reg:CC 0))])]
  335.   ""
  336.   "{ operands[3] = gen_reg_rtx (SImode); }")
  337.  
  338. (define_expand "seqdi_special"
  339.   [(set (match_dup 3)
  340.     (xor:DI (match_operand:DI 1 "register_operand" "")
  341.         (match_operand:DI 2 "register_operand" "")))
  342.    (parallel [(set (match_operand:DI 0 "register_operand" "")
  343.            (eq:DI (match_dup 3) (const_int 0)))
  344.           (clobber (reg:CCX 0))])]
  345.   ""
  346.   "{ operands[3] = gen_reg_rtx (DImode); }")
  347.  
  348. (define_expand "snesi_special"
  349.   [(set (match_dup 3)
  350.     (xor:SI (match_operand:SI 1 "register_operand" "")
  351.         (match_operand:SI 2 "register_operand" "")))
  352.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  353.            (ne:SI (match_dup 3) (const_int 0)))
  354.           (clobber (reg:CC 0))])]
  355.   ""
  356.   "{ operands[3] = gen_reg_rtx (SImode); }")
  357.  
  358. (define_expand "snedi_special"
  359.   [(set (match_dup 3)
  360.     (xor:DI (match_operand:DI 1 "register_operand" "")
  361.         (match_operand:DI 2 "register_operand" "")))
  362.    (parallel [(set (match_operand:DI 0 "register_operand" "")
  363.            (ne:DI (match_dup 3) (const_int 0)))
  364.           (clobber (reg:CCX 0))])]
  365.   ""
  366.   "{ operands[3] = gen_reg_rtx (DImode); }")
  367.  
  368. (define_expand "seqdi_special_trunc"
  369.   [(set (match_dup 3)
  370.     (xor:DI (match_operand:DI 1 "register_operand" "")
  371.         (match_operand:DI 2 "register_operand" "")))
  372.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  373.            (eq:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
  374.           (clobber (reg:CC 0))])]
  375.   ""
  376.   "{ operands[3] = gen_reg_rtx (DImode); }")
  377.  
  378. (define_expand "snedi_special_trunc"
  379.   [(set (match_dup 3)
  380.     (xor:DI (match_operand:DI 1 "register_operand" "")
  381.         (match_operand:DI 2 "register_operand" "")))
  382.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  383.            (ne:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
  384.           (clobber (reg:CC 0))])]
  385.   ""
  386.   "{ operands[3] = gen_reg_rtx (DImode); }")
  387.  
  388. (define_expand "seqsi_special_extend"
  389.   [(set (subreg:SI (match_dup 3) 0)
  390.     (xor:SI (match_operand:SI 1 "register_operand" "")
  391.         (match_operand:SI 2 "register_operand" "")))
  392.    (parallel [(set (match_operand:DI 0 "register_operand" "")
  393.            (eq:DI (match_dup 3) (const_int 0)))
  394.           (clobber (reg:CCX 0))])]
  395.   ""
  396.   "{ operands[3] = gen_reg_rtx (DImode); }")
  397.  
  398. (define_expand "snesi_special_extend"
  399.   [(set (subreg:SI (match_dup 3) 0)
  400.     (xor:SI (match_operand:SI 1 "register_operand" "")
  401.         (match_operand:SI 2 "register_operand" "")))
  402.    (parallel [(set (match_operand:DI 0 "register_operand" "")
  403.            (ne:DI (match_dup 3) (const_int 0)))
  404.           (clobber (reg:CCX 0))])]
  405.   ""
  406.   "{ operands[3] = gen_reg_rtx (DImode); }")
  407.  
  408. ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
  409. ;; However, the code handles both SImode and DImode.
  410. (define_expand "seq"
  411.   [(set (match_operand:SI 0 "intreg_operand" "")
  412.     (eq:SI (match_dup 1) (const_int 0)))]
  413.   ""
  414.   "
  415. {
  416.   if (GET_MODE (sparc_compare_op0) == SImode)
  417.     {
  418.       rtx pat;
  419.  
  420.       if (GET_MODE (operands[0]) == SImode)
  421.     pat = gen_seqsi_special (operands[0], sparc_compare_op0,
  422.                  sparc_compare_op1);
  423.       else if (! TARGET_V9)
  424.     FAIL;
  425.       else
  426.     pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
  427.                     sparc_compare_op1);
  428.       emit_insn (pat);
  429.       DONE;
  430.     }
  431.   else if (GET_MODE (sparc_compare_op0) == DImode)
  432.     {
  433.       rtx pat;
  434.  
  435.       if (GET_MODE (operands[0]) == SImode)
  436.     pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
  437.                        sparc_compare_op1);
  438.       else if (! TARGET_V9)
  439.     FAIL;
  440.       else
  441.     pat = gen_seqdi_special (operands[0], sparc_compare_op0,
  442.                  sparc_compare_op1);
  443.       emit_insn (pat);
  444.       DONE;
  445.     }
  446.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  447.     {
  448.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
  449.       emit_insn (gen_sne (operands[0]));
  450.       DONE;
  451.     }      
  452.   else if (TARGET_V9)
  453.     {
  454.       if (gen_v9_scc (EQ, operands))
  455.     DONE;
  456.       /* fall through */
  457.     }
  458.   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
  459. }")
  460.  
  461. ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
  462. ;; However, the code handles both SImode and DImode.
  463. (define_expand "sne"
  464.   [(set (match_operand:SI 0 "intreg_operand" "")
  465.     (ne:SI (match_dup 1) (const_int 0)))]
  466.   ""
  467.   "
  468. {
  469.   if (GET_MODE (sparc_compare_op0) == SImode)
  470.     {
  471.       rtx pat;
  472.  
  473.       if (GET_MODE (operands[0]) == SImode)
  474.     pat = gen_snesi_special (operands[0], sparc_compare_op0,
  475.                  sparc_compare_op1);
  476.       else if (! TARGET_V9)
  477.     FAIL;
  478.       else
  479.     pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
  480.                     sparc_compare_op1);
  481.       emit_insn (pat);
  482.       DONE;
  483.     }
  484.   else if (GET_MODE (sparc_compare_op0) == DImode)
  485.     {
  486.       rtx pat;
  487.  
  488.       if (GET_MODE (operands[0]) == SImode)
  489.     pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
  490.                        sparc_compare_op1);
  491.       else if (! TARGET_V9)
  492.     FAIL;
  493.       else
  494.     pat = gen_snedi_special (operands[0], sparc_compare_op0,
  495.                  sparc_compare_op1);
  496.       emit_insn (pat);
  497.       DONE;
  498.     }
  499.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  500.     {
  501.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
  502.       emit_insn (gen_sne (operands[0]));
  503.       DONE;
  504.     }      
  505.   else if (TARGET_V9)
  506.     {
  507.       if (gen_v9_scc (NE, operands))
  508.     DONE;
  509.       /* fall through */
  510.     }
  511.   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
  512. }")
  513.  
  514. (define_expand "sgt"
  515.   [(set (match_operand:SI 0 "intreg_operand" "")
  516.     (gt:SI (match_dup 1) (const_int 0)))]
  517.   ""
  518.   "
  519. {
  520.   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  521.     {
  522.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
  523.       emit_insn (gen_sne (operands[0]));
  524.       DONE;
  525.     }
  526.   else if (TARGET_V9)
  527.     {
  528.       if (gen_v9_scc (GT, operands))
  529.     DONE;
  530.       /* fall through */
  531.     }
  532.   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
  533. }")
  534.  
  535. (define_expand "slt"
  536.   [(set (match_operand:SI 0 "intreg_operand" "")
  537.     (lt:SI (match_dup 1) (const_int 0)))]
  538.   ""
  539.   "
  540. {
  541.   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  542.     {
  543.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
  544.       emit_insn (gen_sne (operands[0]));
  545.       DONE;
  546.     }
  547.   else if (TARGET_V9)
  548.     {
  549.       if (gen_v9_scc (LT, operands))
  550.     DONE;
  551.       /* fall through */
  552.     }
  553.   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
  554. }")
  555.  
  556. (define_expand "sge"
  557.   [(set (match_operand:SI 0 "intreg_operand" "")
  558.     (ge:SI (match_dup 1) (const_int 0)))]
  559.   ""
  560.   "
  561. {
  562.   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  563.     {
  564.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
  565.       emit_insn (gen_sne (operands[0]));
  566.       DONE;
  567.     }
  568.   else if (TARGET_V9)
  569.     {
  570.       if (gen_v9_scc (GE, operands))
  571.     DONE;
  572.       /* fall through */
  573.     }
  574.   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
  575. }")
  576.  
  577. (define_expand "sle"
  578.   [(set (match_operand:SI 0 "intreg_operand" "")
  579.     (le:SI (match_dup 1) (const_int 0)))]
  580.   ""
  581.   "
  582. {
  583.   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  584.     {
  585.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
  586.       emit_insn (gen_sne (operands[0]));
  587.       DONE;
  588.     }
  589.   else if (TARGET_V9)
  590.     {
  591.       if (gen_v9_scc (LE, operands))
  592.     DONE;
  593.       /* fall through */
  594.     }
  595.   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
  596. }")
  597.  
  598. (define_expand "sgtu"
  599.   [(set (match_operand:SI 0 "intreg_operand" "")
  600.     (gtu:SI (match_dup 1) (const_int 0)))]
  601.   ""
  602.   "
  603. {
  604.   if (! TARGET_V9)
  605.     {
  606.       rtx tem;
  607.  
  608.       /* We can do ltu easily, so if both operands are registers, swap them and
  609.      do a LTU.  */
  610.       if ((GET_CODE (sparc_compare_op0) == REG
  611.        || GET_CODE (sparc_compare_op0) == SUBREG)
  612.       && (GET_CODE (sparc_compare_op1) == REG
  613.           || GET_CODE (sparc_compare_op1) == SUBREG))
  614.     {
  615.       tem = sparc_compare_op0;
  616.       sparc_compare_op0 = sparc_compare_op1;
  617.       sparc_compare_op1 = tem;
  618.       emit_insn (gen_sltu (operands[0]));
  619.       DONE;
  620.     }
  621.     }
  622.   else
  623.     {
  624.       if (gen_v9_scc (GTU, operands))
  625.     DONE;
  626.     }
  627.   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
  628. }")
  629.  
  630. (define_expand "sltu"
  631.   [(set (match_operand:SI 0 "intreg_operand" "")
  632.     (ltu:SI (match_dup 1) (const_int 0)))]
  633.   ""
  634.   "
  635. {
  636.   if (TARGET_V9)
  637.     {
  638.       if (gen_v9_scc (LTU, operands))
  639.     DONE;
  640.     }
  641.   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
  642. }")
  643.  
  644. (define_expand "sgeu"
  645.   [(set (match_operand:SI 0 "intreg_operand" "")
  646.     (geu:SI (match_dup 1) (const_int 0)))]
  647.   ""
  648.   "
  649. {
  650.   if (TARGET_V9)
  651.     {
  652.       if (gen_v9_scc (GEU, operands))
  653.     DONE;
  654.     }
  655.   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
  656. }")
  657.  
  658. (define_expand "sleu"
  659.   [(set (match_operand:SI 0 "intreg_operand" "")
  660.     (leu:SI (match_dup 1) (const_int 0)))]
  661.   ""
  662.   "
  663. {
  664.   if (! TARGET_V9)
  665.     {
  666.       rtx tem;
  667.  
  668.       /* We can do geu easily, so if both operands are registers, swap them and
  669.      do a GEU.  */
  670.       if ((GET_CODE (sparc_compare_op0) == REG
  671.        || GET_CODE (sparc_compare_op0) == SUBREG)
  672.       && (GET_CODE (sparc_compare_op1) == REG
  673.           || GET_CODE (sparc_compare_op1) == SUBREG))
  674.     {
  675.       tem = sparc_compare_op0;
  676.       sparc_compare_op0 = sparc_compare_op1;
  677.       sparc_compare_op1 = tem;
  678.       emit_insn (gen_sgeu (operands[0]));
  679.       DONE;
  680.     }
  681.     }
  682.   else
  683.     {
  684.       if (gen_v9_scc (LEU, operands))
  685.     DONE;
  686.     }
  687.   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  688. }")
  689.  
  690. ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
  691.  
  692. (define_insn "*cmpsi_insn"
  693.   [(set (reg:CC 0)
  694.     (compare:CC (match_operand:SI 0 "register_operand" "r")
  695.             (match_operand:SI 1 "arith_operand" "rI")))]
  696.   ""
  697.   "cmp %r0,%1"
  698.   [(set_attr "type" "compare")])
  699.  
  700. (define_insn "*cmpsf_fpe_sp32"
  701.   [(set (reg:CCFPE 0)
  702.     (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
  703.                (match_operand:SF 1 "register_operand" "f")))]
  704.   "! TARGET_V9 && TARGET_FPU"
  705.   "fcmpes %0,%1"
  706.   [(set_attr "type" "fpcmp")])
  707.  
  708. (define_insn "*cmpdf_fpe_sp32"
  709.   [(set (reg:CCFPE 0)
  710.     (compare:CCFPE (match_operand:DF 0 "register_operand" "e")
  711.                (match_operand:DF 1 "register_operand" "e")))]
  712.   "! TARGET_V9 && TARGET_FPU"
  713.   "fcmped %0,%1"
  714.   [(set_attr "type" "fpcmp")])
  715.  
  716. (define_insn "*cmptf_fpe_sp32"
  717.   [(set (reg:CCFPE 0)
  718.     (compare:CCFPE (match_operand:TF 0 "register_operand" "e")
  719.                (match_operand:TF 1 "register_operand" "e")))]
  720.   "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  721.   "fcmpeq %0,%1"
  722.   [(set_attr "type" "fpcmp")])
  723.  
  724. (define_insn "*cmpsf_fp_sp32"
  725.   [(set (reg:CCFP 0)
  726.     (compare:CCFP (match_operand:SF 0 "register_operand" "f")
  727.               (match_operand:SF 1 "register_operand" "f")))]
  728.   "! TARGET_V9 && TARGET_FPU"
  729.   "fcmps %0,%1"
  730.   [(set_attr "type" "fpcmp")])
  731.  
  732. (define_insn "*cmpdf_fp_sp32"
  733.   [(set (reg:CCFP 0)
  734.     (compare:CCFP (match_operand:DF 0 "register_operand" "e")
  735.               (match_operand:DF 1 "register_operand" "e")))]
  736.   "! TARGET_V9 && TARGET_FPU"
  737.   "fcmpd %0,%1"
  738.   [(set_attr "type" "fpcmp")])
  739.  
  740. (define_insn "*cmptf_fp_sp32"
  741.   [(set (reg:CCFP 0)
  742.     (compare:CCFP (match_operand:TF 0 "register_operand" "e")
  743.               (match_operand:TF 1 "register_operand" "e")))]
  744.   "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  745.   "fcmpq %0,%1"
  746.   [(set_attr "type" "fpcmp")])
  747.  
  748. (define_insn "*cmpdi_sp64"
  749.   [(set (reg:CCX 0)
  750.     (compare:CCX (match_operand:DI 0 "register_operand" "r")
  751.              (match_operand:DI 1 "arith_double_operand" "rHI")))]
  752.   "TARGET_V9"
  753.   "cmp %r0,%1"
  754.   [(set_attr "type" "compare")])
  755.  
  756. (define_insn "*cmpsf_fpe_sp64"
  757.   [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
  758.     (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
  759.                (match_operand:SF 2 "register_operand" "f")))]
  760.   "TARGET_V9 && TARGET_FPU"
  761.   "fcmpes %0,%1,%2"
  762.   [(set_attr "type" "fpcmp")])
  763.  
  764. (define_insn "*cmpdf_fpe_sp64"
  765.   [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
  766.     (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
  767.                (match_operand:DF 2 "register_operand" "e")))]
  768.   "TARGET_V9 && TARGET_FPU"
  769.   "fcmped %0,%1,%2"
  770.   [(set_attr "type" "fpcmp")])
  771.  
  772. (define_insn "*cmptf_fpe_sp64"
  773.   [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
  774.     (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
  775.                (match_operand:TF 2 "register_operand" "e")))]
  776.   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  777.   "fcmpeq %0,%1,%2"
  778.   [(set_attr "type" "fpcmp")])
  779.  
  780. (define_insn "*cmpsf_fp_sp64"
  781.   [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
  782.     (compare:CCFP (match_operand:SF 1 "register_operand" "f")
  783.               (match_operand:SF 2 "register_operand" "f")))]
  784.   "TARGET_V9 && TARGET_FPU"
  785.   "fcmps %0,%1,%2"
  786.   [(set_attr "type" "fpcmp")])
  787.  
  788. (define_insn "*cmpdf_fp_sp64"
  789.   [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
  790.     (compare:CCFP (match_operand:DF 1 "register_operand" "e")
  791.               (match_operand:DF 2 "register_operand" "e")))]
  792.   "TARGET_V9 && TARGET_FPU"
  793.   "fcmpd %0,%1,%2"
  794.   [(set_attr "type" "fpcmp")])
  795.  
  796. (define_insn "*cmptf_fp_sp64"
  797.   [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
  798.     (compare:CCFP (match_operand:TF 1 "register_operand" "e")
  799.               (match_operand:TF 2 "register_operand" "e")))]
  800.   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  801.   "fcmpq %0,%1,%2"
  802.   [(set_attr "type" "fpcmp")])
  803.  
  804. ;; The SEQ and SNE patterns are special because they can be done
  805. ;; without any branching and do not involve a COMPARE.
  806.  
  807. (define_insn "*snesi_zero"
  808.   [(set (match_operand:SI 0 "register_operand" "=r")
  809.     (ne:SI (match_operand:SI 1 "register_operand" "r")
  810.            (const_int 0)))
  811.    (clobber (reg:CC 0))]
  812.   ""
  813.   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
  814.   [(set_attr "type" "unary")
  815.    (set_attr "length" "2")])
  816.  
  817. (define_insn "*neg_snesi_zero"
  818.   [(set (match_operand:SI 0 "register_operand" "=r")
  819.     (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
  820.                (const_int 0))))
  821.    (clobber (reg:CC 0))]
  822.   ""
  823.   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
  824.   [(set_attr "type" "unary")
  825.    (set_attr "length" "2")])
  826.  
  827. (define_insn "*snedi_zero"
  828.   [(set (match_operand:DI 0 "register_operand" "=r")
  829.     (ne:DI (match_operand:DI 1 "register_operand" "r")
  830.            (const_int 0)))
  831.    (clobber (reg:CCX 0))]
  832.   "TARGET_V9"
  833.   "mov 0,%0\;movrnz %1,1,%0"
  834.   [(set_attr "type" "unary")
  835.    (set_attr "length" "2")])
  836.  
  837. (define_insn "*neg_snedi_zero"
  838.   [(set (match_operand:DI 0 "register_operand" "=r")
  839.     (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
  840.                (const_int 0))))
  841.    (clobber (reg:CCX 0))]
  842.   "TARGET_V9"
  843.   "mov 0,%0\;movrnz %1,-1,%0"
  844.   [(set_attr "type" "unary")
  845.    (set_attr "length" "2")])
  846.  
  847. (define_insn "*seqsi_zero"
  848.   [(set (match_operand:SI 0 "register_operand" "=r")
  849.     (eq:SI (match_operand:SI 1 "register_operand" "r")
  850.            (const_int 0)))
  851.    (clobber (reg:CC 0))]
  852.   ""
  853.   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
  854.   [(set_attr "type" "unary")
  855.    (set_attr "length" "2")])
  856.  
  857. (define_insn "*neg_seqsi_zero"
  858.   [(set (match_operand:SI 0 "register_operand" "=r")
  859.     (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
  860.                (const_int 0))))
  861.    (clobber (reg:CC 0))]
  862.   ""
  863.   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
  864.   [(set_attr "type" "unary")
  865.    (set_attr "length" "2")])
  866.  
  867. (define_insn "*seqdi_zero"
  868.   [(set (match_operand:DI 0 "register_operand" "=r")
  869.     (eq:DI (match_operand:DI 1 "register_operand" "r")
  870.            (const_int 0)))
  871.    (clobber (reg:CCX 0))]
  872.   "TARGET_V9"
  873.   "mov 0,%0\;movrz %1,1,%0"
  874.   [(set_attr "type" "unary")
  875.    (set_attr "length" "2")])
  876.  
  877. (define_insn "*neg_seqdi_zero"
  878.   [(set (match_operand:DI 0 "register_operand" "=r")
  879.     (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
  880.                (const_int 0))))
  881.    (clobber (reg:CCX 0))]
  882.   "TARGET_V9"
  883.   "mov 0,%0\;movrz %1,-1,%0"
  884.   [(set_attr "type" "unary")
  885.    (set_attr "length" "2")]) 
  886.  
  887. ;; We can also do (x + (i == 0)) and related, so put them in.
  888. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
  889. ;; versions for v9.
  890.  
  891. (define_insn "*x_plus_i_ne_0"
  892.   [(set (match_operand:SI 0 "register_operand" "=r")
  893.     (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
  894.             (const_int 0))
  895.          (match_operand:SI 2 "register_operand" "r")))
  896.    (clobber (reg:CC 0))]
  897.   ""
  898.   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
  899.   [(set_attr "length" "2")])
  900.  
  901. (define_insn "*x_minus_i_ne_0"
  902.   [(set (match_operand:SI 0 "register_operand" "=r")
  903.     (minus:SI (match_operand:SI 2 "register_operand" "r")
  904.           (ne:SI (match_operand:SI 1 "register_operand" "r")
  905.              (const_int 0))))
  906.    (clobber (reg:CC 0))]
  907.   ""
  908.   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
  909.   [(set_attr "length" "2")])
  910.  
  911. (define_insn "*x_plus_i_eq_0"
  912.   [(set (match_operand:SI 0 "register_operand" "=r")
  913.     (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
  914.             (const_int 0))
  915.          (match_operand:SI 2 "register_operand" "r")))
  916.    (clobber (reg:CC 0))]
  917.   ""
  918.   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
  919.   [(set_attr "length" "2")])
  920.  
  921. (define_insn "*x_minus_i_eq_0"
  922.   [(set (match_operand:SI 0 "register_operand" "=r")
  923.     (minus:SI (match_operand:SI 2 "register_operand" "r")
  924.           (eq:SI (match_operand:SI 1 "register_operand" "r")
  925.              (const_int 0))))
  926.    (clobber (reg:CC 0))]
  927.   ""
  928.   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
  929.   [(set_attr "length" "2")])
  930.  
  931. ;; We can also do GEU and LTU directly, but these operate after a compare.
  932. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
  933. ;; versions for v9.
  934.  
  935. (define_insn "*sltu_insn"
  936.   [(set (match_operand:SI 0 "register_operand" "=r")
  937.     (ltu:SI (reg:CC 0) (const_int 0)))]
  938.   ""
  939.   "addx %%g0,0,%0"
  940.   [(set_attr "type" "misc")])
  941.  
  942. (define_insn "*neg_sltu_insn"
  943.   [(set (match_operand:SI 0 "register_operand" "=r")
  944.     (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
  945.   ""
  946.   "subx %%g0,0,%0"
  947.   [(set_attr "type" "misc")])
  948.  
  949. ;; ??? Combine should canonicalize these next two to the same pattern.
  950. (define_insn "*neg_sltu_minus_x"
  951.   [(set (match_operand:SI 0 "register_operand" "=r")
  952.     (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
  953.           (match_operand:SI 1 "arith_operand" "rI")))]
  954.   ""
  955.   "subx %%g0,%1,%0"
  956.   [(set_attr "type" "unary")])
  957.  
  958. (define_insn "*neg_sltu_plus_x"
  959.   [(set (match_operand:SI 0 "register_operand" "=r")
  960.     (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  961.              (match_operand:SI 1 "arith_operand" "rI"))))]
  962.   ""
  963.   "subx %%g0,%1,%0"
  964.   [(set_attr "type" "unary")])
  965.  
  966. (define_insn "*sgeu_insn"
  967.   [(set (match_operand:SI 0 "register_operand" "=r")
  968.     (geu:SI (reg:CC 0) (const_int 0)))]
  969.   ""
  970.   "subx %%g0,-1,%0"
  971.   [(set_attr "type" "misc")])
  972.  
  973. (define_insn "*neg_sgeu_insn"
  974.   [(set (match_operand:SI 0 "register_operand" "=r")
  975.     (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
  976.   ""
  977.   "addx %%g0,-1,%0"
  978.   [(set_attr "type" "misc")])
  979.  
  980. ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
  981. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
  982. ;; versions for v9.
  983.  
  984. (define_insn "*sltu_plus_x"
  985.   [(set (match_operand:SI 0 "register_operand" "=r")
  986.     (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  987.          (match_operand:SI 1 "arith_operand" "rI")))]
  988.   ""
  989.   "addx %%g0,%1,%0"
  990.   [(set_attr "type" "unary")])
  991.  
  992. (define_insn "*sltu_plus_x_plus_y"
  993.   [(set (match_operand:SI 0 "register_operand" "=r")
  994.     (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  995.          (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  996.               (match_operand:SI 2 "arith_operand" "rI"))))]
  997.   ""
  998.   "addx %1,%2,%0")
  999.  
  1000. (define_insn "*x_minus_sltu"
  1001.   [(set (match_operand:SI 0 "register_operand" "=r")
  1002.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  1003.           (ltu:SI (reg:CC 0) (const_int 0))))]
  1004.   ""
  1005.   "subx %1,0,%0"
  1006.   [(set_attr "type" "unary")])
  1007.  
  1008. ;; ??? Combine should canonicalize these next two to the same pattern.
  1009. (define_insn "*x_minus_y_minus_sltu"
  1010.   [(set (match_operand:SI 0 "register_operand" "=r")
  1011.     (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
  1012.                 (match_operand:SI 2 "arith_operand" "rI"))
  1013.           (ltu:SI (reg:CC 0) (const_int 0))))]
  1014.   ""
  1015.   "subx %1,%2,%0")
  1016.  
  1017. (define_insn "*x_minus_sltu_plus_y"
  1018.   [(set (match_operand:SI 0 "register_operand" "=r")
  1019.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  1020.           (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  1021.                (match_operand:SI 2 "arith_operand" "rI"))))]
  1022.   ""
  1023.   "subx %1,%2,%0")
  1024.  
  1025. (define_insn "*sgeu_plus_x"
  1026.   [(set (match_operand:SI 0 "register_operand" "=r")
  1027.     (plus:SI (geu:SI (reg:CC 0) (const_int 0))
  1028.          (match_operand:SI 1 "register_operand" "r")))]
  1029.   ""
  1030.   "subx %1,-1,%0"
  1031.   [(set_attr "type" "unary")])
  1032.  
  1033. (define_insn "*x_minus_sgeu"
  1034.   [(set (match_operand:SI 0 "register_operand" "=r")
  1035.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  1036.           (geu:SI (reg:CC 0) (const_int 0))))]
  1037.   ""
  1038.   "addx %1,-1,%0"
  1039.   [(set_attr "type" "unary")])
  1040.  
  1041. ;; Now we have the generic scc insns.
  1042. ;; !v9: These will be done using a jump.
  1043. ;; v9: Use conditional moves which are defined elsewhere.
  1044. ;; We have to exclude the cases above, since we will not want combine to
  1045. ;; turn something that does not require a jump into something that does.
  1046.  
  1047. (define_insn "*scc_si"
  1048.   [(set (match_operand:SI 0 "register_operand" "=r")
  1049.     (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
  1050.   ""
  1051.   "* return output_scc_insn (operands, insn); "
  1052.   [(set_attr "type" "multi")
  1053.    (set_attr "length" "3")])
  1054.  
  1055. (define_insn "*scc_di"
  1056.   [(set (match_operand:DI 0 "register_operand" "=r")
  1057.     (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
  1058.   "TARGET_V9"
  1059.   "* return output_scc_insn (operands, insn); "
  1060.   [(set_attr "type" "multi")
  1061.    (set_attr "length" "3")])
  1062.  
  1063. ;; These control RTL generation for conditional jump insns
  1064.  
  1065. ;; The quad-word fp compare library routines all return nonzero to indicate
  1066. ;; true, which is different from the equivalent libgcc routines, so we must
  1067. ;; handle them specially here.
  1068.  
  1069. (define_expand "beq"
  1070.   [(set (pc)
  1071.     (if_then_else (eq (match_dup 1) (const_int 0))
  1072.               (label_ref (match_operand 0 "" ""))
  1073.               (pc)))]
  1074.   ""
  1075.   "
  1076. {
  1077.   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
  1078.       && GET_CODE (sparc_compare_op0) == REG
  1079.       && GET_MODE (sparc_compare_op0) == DImode)
  1080.     {
  1081.       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
  1082.       DONE;
  1083.     }
  1084.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  1085.     {
  1086.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
  1087.       emit_jump_insn (gen_bne (operands[0]));
  1088.       DONE;
  1089.     }      
  1090.   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
  1091. }")
  1092.  
  1093. (define_expand "bne"
  1094.   [(set (pc)
  1095.     (if_then_else (ne (match_dup 1) (const_int 0))
  1096.               (label_ref (match_operand 0 "" ""))
  1097.               (pc)))]
  1098.   ""
  1099.   "
  1100. {
  1101.   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
  1102.       && GET_CODE (sparc_compare_op0) == REG
  1103.       && GET_MODE (sparc_compare_op0) == DImode)
  1104.     {
  1105.       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
  1106.       DONE;
  1107.     }
  1108.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  1109.     {
  1110.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
  1111.       emit_jump_insn (gen_bne (operands[0]));
  1112.       DONE;
  1113.     }      
  1114.   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
  1115. }")
  1116.  
  1117. (define_expand "bgt"
  1118.   [(set (pc)
  1119.     (if_then_else (gt (match_dup 1) (const_int 0))
  1120.               (label_ref (match_operand 0 "" ""))
  1121.               (pc)))]
  1122.   ""
  1123.   "
  1124. {
  1125.   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
  1126.       && GET_CODE (sparc_compare_op0) == REG
  1127.       && GET_MODE (sparc_compare_op0) == DImode)
  1128.     {
  1129.       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
  1130.       DONE;
  1131.     }
  1132.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  1133.     {
  1134.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
  1135.       emit_jump_insn (gen_bne (operands[0]));
  1136.       DONE;
  1137.     }      
  1138.   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
  1139. }")
  1140.  
  1141. (define_expand "bgtu"
  1142.   [(set (pc)
  1143.     (if_then_else (gtu (match_dup 1) (const_int 0))
  1144.               (label_ref (match_operand 0 "" ""))
  1145.               (pc)))]
  1146.   ""
  1147.   "
  1148. { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
  1149. }")
  1150.  
  1151. (define_expand "blt"
  1152.   [(set (pc)
  1153.     (if_then_else (lt (match_dup 1) (const_int 0))
  1154.               (label_ref (match_operand 0 "" ""))
  1155.               (pc)))]
  1156.   ""
  1157.   "
  1158. {
  1159.   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
  1160.       && GET_CODE (sparc_compare_op0) == REG
  1161.       && GET_MODE (sparc_compare_op0) == DImode)
  1162.     {
  1163.       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
  1164.       DONE;
  1165.     }
  1166.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  1167.     {
  1168.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
  1169.       emit_jump_insn (gen_bne (operands[0]));
  1170.       DONE;
  1171.     }      
  1172.   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
  1173. }")
  1174.  
  1175. (define_expand "bltu"
  1176.   [(set (pc)
  1177.     (if_then_else (ltu (match_dup 1) (const_int 0))
  1178.               (label_ref (match_operand 0 "" ""))
  1179.               (pc)))]
  1180.   ""
  1181.   "
  1182. { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
  1183. }")
  1184.  
  1185. (define_expand "bge"
  1186.   [(set (pc)
  1187.     (if_then_else (ge (match_dup 1) (const_int 0))
  1188.               (label_ref (match_operand 0 "" ""))
  1189.               (pc)))]
  1190.   ""
  1191.   "
  1192. {
  1193.   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
  1194.       && GET_CODE (sparc_compare_op0) == REG
  1195.       && GET_MODE (sparc_compare_op0) == DImode)
  1196.     {
  1197.       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
  1198.       DONE;
  1199.     }
  1200.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  1201.     {
  1202.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
  1203.       emit_jump_insn (gen_bne (operands[0]));
  1204.       DONE;
  1205.     }      
  1206.   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
  1207. }")
  1208.  
  1209. (define_expand "bgeu"
  1210.   [(set (pc)
  1211.     (if_then_else (geu (match_dup 1) (const_int 0))
  1212.               (label_ref (match_operand 0 "" ""))
  1213.               (pc)))]
  1214.   ""
  1215.   "
  1216. { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
  1217. }")
  1218.  
  1219. (define_expand "ble"
  1220.   [(set (pc)
  1221.     (if_then_else (le (match_dup 1) (const_int 0))
  1222.               (label_ref (match_operand 0 "" ""))
  1223.               (pc)))]
  1224.   ""
  1225.   "
  1226. {
  1227.   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
  1228.       && GET_CODE (sparc_compare_op0) == REG
  1229.       && GET_MODE (sparc_compare_op0) == DImode)
  1230.     {
  1231.       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
  1232.       DONE;
  1233.     }
  1234.   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
  1235.     {
  1236.       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
  1237.       emit_jump_insn (gen_bne (operands[0]));
  1238.       DONE;
  1239.     }      
  1240.   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
  1241. }")
  1242.  
  1243. (define_expand "bleu"
  1244.   [(set (pc)
  1245.     (if_then_else (leu (match_dup 1) (const_int 0))
  1246.               (label_ref (match_operand 0 "" ""))
  1247.               (pc)))]
  1248.   ""
  1249.   "
  1250. { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  1251. }")
  1252.  
  1253. ;; Now match both normal and inverted jump.
  1254.  
  1255. (define_insn "*normal_branch"
  1256.   [(set (pc)
  1257.     (if_then_else (match_operator 0 "noov_compare_op"
  1258.                       [(reg 0) (const_int 0)])
  1259.               (label_ref (match_operand 1 "" ""))
  1260.               (pc)))]
  1261.   ""
  1262.   "*
  1263. {
  1264.   return output_cbranch (operands[0], 0, 1, 0,
  1265.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1266.              ! final_sequence);
  1267. }"
  1268.   [(set_attr "type" "branch")])
  1269.  
  1270. (define_insn "*inverted_branch"
  1271.   [(set (pc)
  1272.     (if_then_else (match_operator 0 "noov_compare_op"
  1273.                       [(reg 0) (const_int 0)])
  1274.               (pc)
  1275.               (label_ref (match_operand 1 "" ""))))]
  1276.   ""
  1277.   "*
  1278. {
  1279.   return output_cbranch (operands[0], 0, 1, 1,
  1280.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1281.              ! final_sequence);
  1282. }"
  1283.   [(set_attr "type" "branch")])
  1284.  
  1285. (define_insn "*normal_fp_branch_sp64"
  1286.   [(set (pc)
  1287.     (if_then_else (match_operator 0 "comparison_operator"
  1288.                       [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
  1289.                        (const_int 0)])
  1290.               (label_ref (match_operand 2 "" ""))
  1291.               (pc)))]
  1292.   "TARGET_V9"
  1293.   "*
  1294. {
  1295.   return output_cbranch (operands[0], operands[1], 2, 0,
  1296.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1297.              ! final_sequence);
  1298. }"
  1299.   [(set_attr "type" "branch")])
  1300.  
  1301. (define_insn "*inverted_fp_branch_sp64"
  1302.   [(set (pc)
  1303.     (if_then_else (match_operator 0 "comparison_operator"
  1304.                       [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
  1305.                        (const_int 0)])
  1306.               (pc)
  1307.               (label_ref (match_operand 2 "" ""))))]
  1308.   "TARGET_V9"
  1309.   "*
  1310. {
  1311.   return output_cbranch (operands[0], operands[1], 2, 1,
  1312.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1313.              ! final_sequence);
  1314. }"
  1315.   [(set_attr "type" "branch")])
  1316.  
  1317. (define_insn "*normal_fpe_branch_sp64"
  1318.   [(set (pc)
  1319.     (if_then_else (match_operator 0 "comparison_operator"
  1320.                       [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
  1321.                        (const_int 0)])
  1322.               (label_ref (match_operand 2 "" ""))
  1323.               (pc)))]
  1324.   "TARGET_V9"
  1325.   "*
  1326. {
  1327.   return output_cbranch (operands[0], operands[1], 2, 0,
  1328.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1329.              ! final_sequence);
  1330. }"
  1331.   [(set_attr "type" "branch")])
  1332.  
  1333. (define_insn "*inverted_fpe_branch_sp64"
  1334.   [(set (pc)
  1335.     (if_then_else (match_operator 0 "comparison_operator"
  1336.                       [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
  1337.                        (const_int 0)])
  1338.               (pc)
  1339.               (label_ref (match_operand 2 "" ""))))]
  1340.   "TARGET_V9"
  1341.   "*
  1342. {
  1343.   return output_cbranch (operands[0], operands[1], 2, 1,
  1344.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1345.              ! final_sequence);
  1346. }"
  1347.   [(set_attr "type" "branch")])
  1348.  
  1349. ;; Sparc V9-specific jump insns.  None of these are guaranteed to be
  1350. ;; in the architecture.
  1351.  
  1352. ;; There are no 32 bit brreg insns.
  1353.  
  1354. (define_insn "*normal_int_branch_sp64"
  1355.   [(set (pc)
  1356.     (if_then_else (match_operator 0 "v9_regcmp_op"
  1357.                       [(match_operand:DI 1 "register_operand" "r")
  1358.                        (const_int 0)])
  1359.               (label_ref (match_operand 2 "" ""))
  1360.               (pc)))]
  1361.   "TARGET_V9"
  1362.   "*
  1363. {
  1364.   return output_v9branch (operands[0], 1, 2, 0,
  1365.               final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1366.               ! final_sequence);
  1367. }"
  1368.   [(set_attr "type" "branch")])
  1369.  
  1370. (define_insn "*inverted_int_branch_sp64"
  1371.   [(set (pc)
  1372.     (if_then_else (match_operator 0 "v9_regcmp_op"
  1373.                       [(match_operand:DI 1 "register_operand" "r")
  1374.                        (const_int 0)])
  1375.               (pc)
  1376.               (label_ref (match_operand 2 "" ""))))]
  1377.   "TARGET_V9"
  1378.   "*
  1379. {
  1380.   return output_v9branch (operands[0], 1, 2, 1,
  1381.               final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  1382.               ! final_sequence);
  1383. }"
  1384.   [(set_attr "type" "branch")])
  1385.  
  1386. ;; Esoteric move insns (lo_sum, high, pic).
  1387.  
  1388. (define_insn "*lo_sum_si"
  1389.   [(set (match_operand:SI 0 "register_operand" "=r")
  1390.     (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1391.            (match_operand:SI 2 "immediate_operand" "in")))]
  1392.   ""
  1393.   ;; V9 needs "add" because of the code models.  We still use "or" for v8
  1394.   ;; so we can compare the old compiler with the new.
  1395.   "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
  1396.   ;; Need to set length for this arith insn because operand2
  1397.   ;; is not an "arith_operand".
  1398.   [(set_attr "length" "1")])
  1399.  
  1400. ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
  1401. ;; confuse them with real addresses.
  1402. (define_insn "*pic_lo_sum_si"
  1403.   [(set (match_operand:SI 0 "register_operand" "=r")
  1404.     (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1405.            (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
  1406.   ""
  1407.   ;; V9 needs "add" because of the code models.  We still use "or" for v8
  1408.   ;; so we can compare the old compiler with the new.
  1409.   "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
  1410.   ;; Need to set length for this arith insn because operand2
  1411.   ;; is not an "arith_operand".
  1412.   [(set_attr "length" "1")])
  1413.  
  1414. ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
  1415. ;; confuse them with real addresses.
  1416. (define_insn "*pic_sethi_si"
  1417.   [(set (match_operand:SI 0 "register_operand" "=r")
  1418.     (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
  1419.   "check_pic (1)"
  1420.   "sethi %%hi(%a1),%0"
  1421.   [(set_attr "type" "move")
  1422.    (set_attr "length" "1")])
  1423.  
  1424. (define_insn "*sethi_si"
  1425.   [(set (match_operand:SI 0 "register_operand" "=r")
  1426.     (high:SI (match_operand 1 "" "")))]
  1427.   "check_pic (1)"
  1428.   "sethi %%hi(%a1),%0"
  1429.   [(set_attr "type" "move")
  1430.    (set_attr "length" "1")])
  1431.  
  1432. (define_insn "*sethi_hi"
  1433.   [(set (match_operand:HI 0 "register_operand" "=r")
  1434.     (high:HI (match_operand 1 "" "")))]
  1435.   "check_pic (1)"
  1436.   "sethi %%hi(%a1),%0"
  1437.   [(set_attr "type" "move")
  1438.    (set_attr "length" "1")])
  1439.  
  1440. ;; Special pic pattern, for loading the address of a label into a register.
  1441. ;; It clobbers o7 because the call puts the return address (i.e. pc value)
  1442. ;; there.
  1443.  
  1444. (define_insn "*move_pic_label_si"
  1445.   [(set (match_operand:SI 0 "register_operand" "=r")
  1446.     (match_operand:SI 1 "move_pic_label" "i"))
  1447.    (set (reg:SI 15) (pc))]
  1448.   ""
  1449.   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
  1450.   [(set_attr "type" "multi")
  1451.    (set_attr "length" "4")])
  1452.  
  1453. ;; v9 special pic pattern, for loading the address of a label into a register.
  1454.  
  1455. (define_insn "*move_pic_label_di"
  1456.   [(set (match_operand:DI 0 "register_operand" "=r")
  1457.     (match_operand:DI 1 "move_pic_label" "i"))
  1458.    (set (reg:DI 15) (pc))]
  1459.   "TARGET_V9"
  1460.   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
  1461.   [(set_attr "type" "multi")
  1462.    (set_attr "length" "4")])
  1463.  
  1464. (define_insn "*lo_sum_di_sp32"
  1465.   [(set (match_operand:DI 0 "register_operand" "=r")
  1466.     (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
  1467.            (match_operand:DI 2 "immediate_operand" "in")))]
  1468.   "! TARGET_V9"
  1469.   "*
  1470. {
  1471.   /* Don't output a 64 bit constant, since we can't trust the assembler to
  1472.      handle it correctly.  */
  1473.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  1474.     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
  1475.   return \"or %R1,%%lo(%a2),%R0\";
  1476. }"
  1477.   ;; Need to set length for this arith insn because operand2
  1478.   ;; is not an "arith_operand".
  1479.   [(set_attr "length" "1")])
  1480.  
  1481. ;; ??? Gas does not handle %lo(DI), so we use the same code for ! TARGET_V9.
  1482. ;; ??? The previous comment is obsolete.
  1483. ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
  1484.  
  1485. (define_insn "*lo_sum_di_sp64"
  1486.   [(set (match_operand:DI 0 "register_operand" "=r")
  1487.     (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
  1488.            (match_operand:DI 2 "immediate_operand" "in")))]
  1489.   "TARGET_V9"
  1490.   "*
  1491. {
  1492.   /* Don't output a 64 bit constant, since we can't trust the assembler to
  1493.      handle it correctly.  */
  1494.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  1495.     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
  1496.   /* Note that we use add here.  This is important because Medium/Anywhere
  1497.      code model support depends on it.  */
  1498.   return \"add %1,%%lo(%a2),%0\";
  1499. }"
  1500.   ;; Need to set length for this arith insn because operand2
  1501.   ;; is not an "arith_operand".
  1502.   [(set_attr "length" "1")])
  1503.  
  1504. (define_insn "*sethi_di_sp32"
  1505.   [(set (match_operand:DI 0 "register_operand" "=r")
  1506.     (high:DI (match_operand 1 "" "")))]
  1507.   "! TARGET_V9 && check_pic (1)"
  1508.   "*
  1509. {
  1510.   rtx op0 = operands[0];
  1511.   rtx op1 = operands[1];
  1512.  
  1513.   if (GET_CODE (op1) == CONST_INT)
  1514.     {
  1515.       operands[0] = operand_subword (op0, 1, 0, DImode);
  1516.       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
  1517.  
  1518.       operands[0] = operand_subword (op0, 0, 0, DImode);
  1519.       if (INTVAL (op1) < 0)
  1520.     return \"mov -1,%0\";
  1521.       else
  1522.     return \"mov 0,%0\";
  1523.     }
  1524.   else if (GET_CODE (op1) == CONST_DOUBLE)
  1525.     {
  1526.       operands[0] = operand_subword (op0, 1, 0, DImode);
  1527.       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
  1528.       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
  1529.  
  1530.       operands[0] = operand_subword (op0, 0, 0, DImode);
  1531.       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
  1532.       return singlemove_string (operands);
  1533.     }
  1534.   else
  1535.     abort ();
  1536.   return \"\";
  1537. }"
  1538.   [(set_attr "type" "move")
  1539.    (set_attr "length" "2")])
  1540.  
  1541. ;;; ??? This pattern originally clobbered a scratch register.  However, this
  1542. ;;; is invalid, the movdi pattern may not use a temp register because it
  1543. ;;; may be called from reload to reload a DImode value.  In that case, we
  1544. ;;; end up with a scratch register that never gets allocated.  To avoid this,
  1545. ;;; we use global register 1 which is never otherwise used by gcc as a temp.
  1546. ;;; The correct solution here might be to force DImode constants to memory,
  1547. ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
  1548. ;;; 1 will then no longer need to be considered a fixed reg.
  1549.  
  1550. ;;; Gas doesn't have any 64 bit constant support, so don't use %uhi and %ulo
  1551. ;;; on constants.  Symbols have to be handled by the linker, so we must use
  1552. ;;; %uhi and %ulo for them, but gas will handle these correctly.
  1553. ;;; ??? This comment is obsolete, gas handles them now.
  1554.  
  1555. (define_insn "*sethi_di_sp64"
  1556.   [(set (match_operand:DI 0 "register_operand" "=r")
  1557.     (high:DI (match_operand 1 "const_double_operand" "")))
  1558.    (clobber (reg:DI 1))]
  1559.   "TARGET_V9 && check_pic (1)"
  1560.   "*
  1561. {
  1562.   rtx high, low;
  1563.   
  1564.   split_double (operands[1], &high, &low);
  1565.  
  1566.   if (high == const0_rtx)
  1567.     {
  1568.       operands[1] = low;
  1569.       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
  1570.     }
  1571.   else
  1572.     {
  1573.       operands[1] = high;
  1574.       output_asm_insn (singlemove_string (operands), operands);
  1575.  
  1576.       operands[1] = low;
  1577.       output_asm_insn (\"sllx %0,32,%0\", operands);
  1578.       if (low != const0_rtx)
  1579.     output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
  1580.     }
  1581. }"
  1582.   [(set_attr "type" "move")
  1583.    (set_attr "length" "5")])
  1584.  
  1585. ;; Most of the required support for the various code models is here.
  1586. ;; We can do this because sparcs need the high insn to load the address.  We
  1587. ;; just need to get high to do the right thing for each code model.  Then each
  1588. ;; uses the same "%X+%lo(...)" in the load/store insn.
  1589.  
  1590. ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are
  1591. ;; always 0.
  1592. ;; When TARGET_MEDANY, the upper 32 bits of function addresses are 0.
  1593. ;; The data segment has a maximum size of 32 bits, but may be located anywhere.
  1594. ;; MEDANY_BASE_REG contains the start address, currently %g4.
  1595. ;; When TARGET_FULLANY, symbolic addresses are 64 bits.
  1596.  
  1597. (define_insn "*sethi_di_medlow"
  1598.   [(set (match_operand:DI 0 "register_operand" "=r")
  1599.     (high:DI (match_operand 1 "" "")))
  1600. ;; ??? Why the clobber?
  1601.    (clobber (reg:DI 1))]
  1602.   "TARGET_MEDLOW && check_pic (1)"
  1603.   "sethi %%hi(%a1),%0"
  1604.   [(set_attr "type" "move")
  1605.    (set_attr "length" "1")])
  1606.  
  1607. ;; WARNING: %0 gets %hi(%1)+%g4.
  1608. ;;          You cannot OR in %lo(%1), it must be added in.
  1609.  
  1610. (define_insn "*sethi_di_medany_data"
  1611.   [(set (match_operand:DI 0 "register_operand" "=r")
  1612.     (high:DI (match_operand 1 "data_segment_operand" "")))
  1613. ;; ??? Why the clobber?
  1614.    (clobber (reg:DI 1))]
  1615.   "TARGET_MEDANY && check_pic (1)"
  1616.   "sethi %%hi(%a1),%0; add %0,%%g4,%0"
  1617.   [(set_attr "type" "move")
  1618.    (set_attr "length" "2")])
  1619.  
  1620. (define_insn "*sethi_di_medany_text"
  1621.   [(set (match_operand:DI 0 "register_operand" "=r")
  1622.     (high:DI (match_operand 1 "text_segment_operand" "")))
  1623. ;; ??? Why the clobber?
  1624.    (clobber (reg:DI 1))]
  1625.   "TARGET_MEDANY && check_pic (1)"
  1626.   "sethi %%hi(%a1),%0"
  1627.   [(set_attr "type" "move")
  1628.    (set_attr "length" "1")])
  1629.  
  1630. (define_insn "*sethi_di_fullany"
  1631.   [(set (match_operand:DI 0 "register_operand" "=r")
  1632.     (high:DI (match_operand 1 "" "")))
  1633.    (clobber (reg:DI 1))]
  1634.   "TARGET_FULLANY && check_pic (1)"
  1635.   "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
  1636.   [(set_attr "type" "move")
  1637.    (set_attr "length" "5")])
  1638.  
  1639. ;; Move instructions
  1640.  
  1641. (define_expand "movqi"
  1642.   [(set (match_operand:QI 0 "general_operand" "")
  1643.     (match_operand:QI 1 "general_operand" ""))]
  1644.   ""
  1645.   "
  1646. {
  1647.   if (emit_move_sequence (operands, QImode))
  1648.     DONE;
  1649. }")
  1650.  
  1651. (define_insn "*movqi_insn"
  1652.   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
  1653.     (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
  1654.   "register_operand (operands[0], QImode)
  1655.    || register_operand (operands[1], QImode)
  1656.    || operands[1] == const0_rtx"
  1657.   "@
  1658.    mov %1,%0
  1659.    sethi %%hi(%a1),%0
  1660.    ldub %1,%0
  1661.    stb %r1,%0"
  1662.   [(set_attr "type" "move,move,load,store")
  1663.    (set_attr "length" "*,1,*,1")])
  1664.  
  1665. (define_insn "*lo_sum_qi"
  1666.   [(set (match_operand:QI 0 "register_operand" "=r")
  1667.     (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
  1668.                   (match_operand 2 "immediate_operand" "in")) 0))]
  1669.   ""
  1670.   "or %1,%%lo(%a2),%0"
  1671.   [(set_attr "length" "1")])
  1672.  
  1673. (define_insn "*store_qi"
  1674.   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  1675.     (match_operand:QI 1 "reg_or_0_operand" "rJ"))
  1676.    (clobber (match_scratch:SI 2 "=&r"))]
  1677.   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
  1678.   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
  1679.   [(set_attr "type" "store")
  1680.    (set_attr "length" "2")])
  1681.  
  1682. (define_expand "movhi"
  1683.   [(set (match_operand:HI 0 "general_operand" "")
  1684.     (match_operand:HI 1 "general_operand" ""))]
  1685.   ""
  1686.   "
  1687. {
  1688.   if (emit_move_sequence (operands, HImode))
  1689.     DONE;
  1690. }")
  1691.  
  1692. (define_insn "*movhi_insn"
  1693.   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
  1694.     (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
  1695.   "register_operand (operands[0], HImode)
  1696.    || register_operand (operands[1], HImode)
  1697.    || operands[1] == const0_rtx"
  1698.   "@
  1699.    mov %1,%0
  1700.    sethi %%hi(%a1),%0
  1701.    lduh %1,%0
  1702.    sth %r1,%0"
  1703.   [(set_attr "type" "move,move,load,store")
  1704.    (set_attr "length" "*,1,*,1")])
  1705.  
  1706. (define_insn "*lo_sum_hi"
  1707.   [(set (match_operand:HI 0 "register_operand" "=r")
  1708.     (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
  1709.            (match_operand 2 "immediate_operand" "in")))]
  1710.   ""
  1711.   "or %1,%%lo(%a2),%0"
  1712.   [(set_attr "length" "1")])
  1713.  
  1714. (define_insn "*store_hi"
  1715.   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
  1716.     (match_operand:HI 1 "reg_or_0_operand" "rJ"))
  1717.    (clobber (match_scratch:SI 2 "=&r"))]
  1718.   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
  1719.   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
  1720.   [(set_attr "type" "store")
  1721.    (set_attr "length" "2")])
  1722.  
  1723. (define_expand "movsi"
  1724.   [(set (match_operand:SI 0 "general_operand" "")
  1725.     (match_operand:SI 1 "general_operand" ""))]
  1726.   ""
  1727.   "
  1728. {
  1729.   if (emit_move_sequence (operands, SImode))
  1730.     DONE;
  1731. }")
  1732.  
  1733. ;; We must support both 'r' and 'f' registers here, because combine may
  1734. ;; convert SFmode hard registers to SImode hard registers when simplifying
  1735. ;; subreg sets.
  1736.  
  1737. ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
  1738. ;; problems with register allocation.  Reload might try to put an integer
  1739. ;; in an fp register, or an fp number is an integer register.
  1740.  
  1741. (define_insn "*movsi_insn"
  1742.   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
  1743.     (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
  1744.   "register_operand (operands[0], SImode)
  1745.    || register_operand (operands[1], SImode)
  1746.    || operands[1] == const0_rtx"
  1747.   "@
  1748.    mov %1,%0
  1749.    fmovs %1,%0
  1750.    sethi %%hi(%a1),%0
  1751.    ld %1,%0
  1752.    ld %1,%0
  1753.    st %r1,%0
  1754.    st %r1,%0"
  1755.   [(set_attr "type" "move,fp,move,load,load,store,store")
  1756.    (set_attr "length" "*,*,1,*,*,*,*")])
  1757.  
  1758. (define_insn "*store_si"
  1759.   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
  1760.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  1761.    (clobber (match_scratch:SI 2 "=&r"))]
  1762.   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
  1763.   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
  1764.   [(set_attr "type" "store")
  1765.    (set_attr "length" "2")])
  1766.  
  1767. (define_expand "movdi"
  1768.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
  1769.     (match_operand:DI 1 "general_operand" ""))]
  1770.   ""
  1771.   "
  1772. {
  1773.   if (emit_move_sequence (operands, DImode))
  1774.     DONE;
  1775. }")
  1776.  
  1777. (define_insn "*movdi_sp32_insn"
  1778.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
  1779.     (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
  1780.   "! TARGET_V9
  1781.    && (register_operand (operands[0], DImode)
  1782.        || register_operand (operands[1], DImode)
  1783.        || operands[1] == const0_rtx)"
  1784.   "*
  1785. {
  1786.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  1787.     return output_fp_move_double (operands);
  1788.   return output_move_double (operands);
  1789. }"
  1790.   [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
  1791.    (set_attr "length" "2,1,1,3,3,3,2,3,3")])
  1792.  
  1793. ;;; ??? The trick used below can be extended to load any negative 32 bit
  1794. ;;; constant in two instructions.  Currently the compiler will use HIGH/LO_SUM
  1795. ;;; for anything not matching the HIK constraints, which results in 5
  1796. ;;; instructions.  Positive 32 bit constants can be loaded in the obvious way
  1797. ;;; with sethi/ori.  To extend the trick, in the xor instruction, use 
  1798. ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
  1799. ;;; This needs the original value of operands[1], not the inverted value.
  1800.  
  1801. (define_insn "*movdi_sp64_insn"
  1802.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
  1803.     (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
  1804.   "TARGET_V9
  1805.    && (register_operand (operands[0], DImode)
  1806.        || register_operand (operands[1], DImode)
  1807.        || operands[1] == const0_rtx)"
  1808.   "*
  1809. {
  1810.   switch (which_alternative)
  1811.     {
  1812.     case 0:
  1813.       return \"mov %1,%0\";
  1814.     case 1:
  1815.       /* Sethi does not sign extend, so we must use a little trickery
  1816.      to use it for negative numbers.  Invert the constant before
  1817.      loading it in, then use a xor immediate to invert the loaded bits
  1818.      (along with the upper 32 bits) to the desired constant.  This
  1819.      works because the sethi and immediate fields overlap.  */
  1820.  
  1821.       if ((INTVAL (operands[1]) & 0x80000000) == 0)
  1822.     return \"sethi %%hi(%a1),%0\";
  1823.       else
  1824.     {
  1825.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1826.                  ~ INTVAL (operands[1]));
  1827.       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
  1828.       /* The low 10 bits are already zero, but invert the rest.
  1829.          Assemblers don't accept 0x1c00, so use -0x400 instead.  */
  1830.       return \"xor %0,-0x400,%0\";
  1831.     }
  1832.     case 2:
  1833.       return \"ldx %1,%0\";
  1834.     case 3:
  1835.       return \"stx %r1,%0\";
  1836.     case 4:
  1837.       return \"mov %1,%0\";
  1838.     case 5:
  1839.       return \"ldd %1,%0\";
  1840.     case 6:
  1841.       return \"std %1,%0\";
  1842.     }
  1843. }"
  1844.   [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
  1845.    (set_attr "length" "1,2,1,1,1,1,1")])
  1846.  
  1847. ;; ??? There's no symbolic (set (mem:DI ...) ...).
  1848. ;; Experimentation with v9 suggested one isn't needed.
  1849.  
  1850. ;; Block move insns.
  1851.  
  1852. ;; ??? We get better code without it.  See output_block_move in sparc.c.
  1853.  
  1854. ;; The definition of this insn does not really explain what it does,
  1855. ;; but it should suffice
  1856. ;; that anything generated as this insn will be recognized as one
  1857. ;; and that it will not successfully combine with anything.
  1858. ;(define_expand "movstrsi"
  1859. ;  [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
  1860. ;           (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  1861. ;          (use (match_operand:SI 2 "nonmemory_operand" ""))
  1862. ;          (use (match_operand:SI 3 "immediate_operand" ""))
  1863. ;          (clobber (match_dup 0))
  1864. ;          (clobber (match_dup 1))
  1865. ;          (clobber (match_scratch:SI 4 ""))
  1866. ;          (clobber (reg:SI 0))
  1867. ;          (clobber (reg:SI 1))])]
  1868. ;  ""
  1869. ;  "
  1870. ;{
  1871. ;  /* If the size isn't known, don't emit inline code.  output_block_move
  1872. ;     would output code that's much slower than the library function.
  1873. ;     Also don't output code for large blocks.  */
  1874. ;  if (GET_CODE (operands[2]) != CONST_INT
  1875. ;      || GET_CODE (operands[3]) != CONST_INT
  1876. ;      || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
  1877. ;    FAIL;
  1878. ;
  1879. ;  operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  1880. ;  operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  1881. ;  operands[2] = force_not_mem (operands[2]);
  1882. ;}")
  1883.  
  1884. ;(define_insn "*block_move_insn"
  1885. ;  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
  1886. ;    (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
  1887. ;   (use (match_operand:SI 2 "nonmemory_operand" "rn"))
  1888. ;   (use (match_operand:SI 3 "immediate_operand" "i"))
  1889. ;   (clobber (match_dup 0))
  1890. ;   (clobber (match_dup 1))
  1891. ;   (clobber (match_scratch:SI 4 "=&r"))
  1892. ;   (clobber (reg:SI 0))
  1893. ;   (clobber (reg:SI 1))]
  1894. ;  ""
  1895. ;  "* return output_block_move (operands);"
  1896. ;  [(set_attr "type" "multi")
  1897. ;   (set_attr "length" "6")])
  1898.  
  1899. ;; Floating point move insns
  1900.  
  1901. ;; This pattern forces (set (reg:SF ...) (const_double ...))
  1902. ;; to be reloaded by putting the constant into memory.
  1903. ;; It must come before the more general movsf pattern.
  1904. (define_insn "*movsf_const_insn"
  1905.   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
  1906.     (match_operand:SF 1 "" "?F,m,G"))]
  1907.   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
  1908.   "*
  1909. {
  1910.   switch (which_alternative)
  1911.     {
  1912.     case 0:
  1913.       return singlemove_string (operands);
  1914.     case 1:
  1915.       return \"ld %1,%0\";
  1916.     case 2:
  1917.       return \"st %%g0,%0\";
  1918.     }
  1919. }"
  1920.   [(set_attr "type" "load,fpload,store")
  1921.    (set_attr "length" "2,1,1")])
  1922.  
  1923. (define_expand "movsf"
  1924.   [(set (match_operand:SF 0 "general_operand" "")
  1925.     (match_operand:SF 1 "general_operand" ""))]
  1926.   ""
  1927.   "
  1928. {
  1929.   if (emit_move_sequence (operands, SFmode))
  1930.     DONE;
  1931. }")
  1932.  
  1933. (define_insn "*movsf_insn"
  1934.   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
  1935.     (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
  1936.   "TARGET_FPU
  1937.    && (register_operand (operands[0], SFmode)
  1938.        || register_operand (operands[1], SFmode))"
  1939.   "@
  1940.    fmovs %1,%0
  1941.    mov %1,%0
  1942.    ld %1,%0
  1943.    ld %1,%0
  1944.    st %r1,%0
  1945.    st %r1,%0"
  1946.   [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
  1947.  
  1948. ;; Exactly the same as above, except that all `f' cases are deleted.
  1949. ;; This is necessary to prevent reload from ever trying to use a `f' reg
  1950. ;; when -mno-fpu.
  1951.  
  1952. (define_insn "*movsf_no_f_insn"
  1953.   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
  1954.     (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
  1955.   "! TARGET_FPU
  1956.    && (register_operand (operands[0], SFmode)
  1957.        || register_operand (operands[1], SFmode))"
  1958.   "@
  1959.    mov %1,%0
  1960.    ld %1,%0
  1961.    st %r1,%0"
  1962.   [(set_attr "type" "move,load,store")])
  1963.  
  1964. (define_insn "*store_sf"
  1965.   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
  1966.     (match_operand:SF 1 "reg_or_0_operand" "rfG"))
  1967.    (clobber (match_scratch:SI 2 "=&r"))]
  1968.   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
  1969.   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
  1970.   [(set_attr "type" "store")
  1971.    (set_attr "length" "2")])
  1972.  
  1973. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  1974. ;; to be reloaded by putting the constant into memory.
  1975. ;; It must come before the more general movdf pattern.
  1976.  
  1977. (define_insn "*movdf_const_insn"
  1978.   [(set (match_operand:DF 0 "general_operand" "=?r,e,o")
  1979.     (match_operand:DF 1 "" "?F,m,G"))]
  1980.   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
  1981.   "*
  1982. {
  1983.   switch (which_alternative)
  1984.     {
  1985.     case 0:
  1986.       return output_move_double (operands);
  1987.     case 1:
  1988.       return output_fp_move_double (operands);
  1989.     case 2:
  1990.       if (TARGET_V9)
  1991.     {
  1992.       return \"stx %%g0,%0\";
  1993.     }
  1994.       else
  1995.     {
  1996.       operands[1] = adj_offsettable_operand (operands[0], 4);
  1997.       return \"st %%g0,%0\;st %%g0,%1\";
  1998.     }
  1999.     }
  2000. }"
  2001.   [(set_attr "type" "load,fpload,store")
  2002.    (set_attr "length" "3,3,3")])
  2003.  
  2004. (define_expand "movdf"
  2005.   [(set (match_operand:DF 0 "general_operand" "")
  2006.     (match_operand:DF 1 "general_operand" ""))]
  2007.   ""
  2008.   "
  2009. {
  2010.   if (emit_move_sequence (operands, DFmode))
  2011.     DONE;
  2012. }")
  2013.  
  2014. (define_insn "*movdf_insn"
  2015.   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
  2016.     (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
  2017.   "TARGET_FPU
  2018.    && (register_operand (operands[0], DFmode)
  2019.        || register_operand (operands[1], DFmode))"
  2020.   "*
  2021. {
  2022.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  2023.     return output_fp_move_double (operands);
  2024.   return output_move_double (operands);
  2025. }"
  2026.   [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
  2027.    (set_attr "length" "1,1,2,2,3,3,3,3")])
  2028.  
  2029. ;; Exactly the same as above, except that all `e' cases are deleted.
  2030. ;; This is necessary to prevent reload from ever trying to use a `e' reg
  2031. ;; when -mno-fpu.
  2032.  
  2033. (define_insn "*movdf_no_e_insn"
  2034.   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
  2035.     (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
  2036.   "! TARGET_FPU
  2037.    && (register_operand (operands[0], DFmode)
  2038.        || register_operand (operands[1], DFmode))"
  2039.   "* return output_move_double (operands);"
  2040.   [(set_attr "type" "store,load,move,store,load")
  2041.    (set_attr "length" "1,1,2,3,3")])
  2042.  
  2043. ;; Must handle overlapping registers here, since parameters can be unaligned
  2044. ;; in registers.
  2045. ;; ??? Do we need a v9 version of this?
  2046. (define_split
  2047.   [(set (match_operand:DF 0 "register_operand" "")
  2048.     (match_operand:DF 1 "register_operand" ""))]
  2049.   "! TARGET_V9 && reload_completed"
  2050.   [(set (match_dup 2) (match_dup 3))
  2051.    (set (match_dup 4) (match_dup 5))]
  2052.   "
  2053. {
  2054.   rtx first_set = operand_subword (operands[0], 0, 0, DFmode);
  2055.   rtx second_use = operand_subword (operands[1], 1, 0, DFmode);
  2056.  
  2057.   if (REGNO (first_set) == REGNO (second_use))
  2058.     {
  2059.       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
  2060.       operands[3] = second_use;
  2061.       operands[4] = first_set;
  2062.       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
  2063.     }
  2064.   else
  2065.     {
  2066.       operands[2] = first_set;
  2067.       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
  2068.       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
  2069.       operands[5] = second_use;
  2070.     }
  2071. }")
  2072.  
  2073. (define_insn "*store_df"
  2074.   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
  2075.     (match_operand:DF 1 "reg_or_0_operand" "re,G"))
  2076.    (clobber (match_scratch:SI 2 "=&r,&r"))]
  2077.   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
  2078.   "*
  2079. {
  2080.   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
  2081.   if (which_alternative == 0)
  2082.     return \"std %1,[%2+%%lo(%a0)]\";
  2083.   else
  2084.     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
  2085. }"
  2086.   [(set_attr "type" "store")
  2087.    (set_attr "length" "3")])
  2088.  
  2089. ;; This pattern forces (set (reg:TF ...) (const_double ...))
  2090. ;; to be reloaded by putting the constant into memory.
  2091. ;; It must come before the more general movtf pattern.
  2092. (define_insn "*movtf_const_insn"
  2093.   [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
  2094.     (match_operand:TF 1 "" "?F,m,G"))]
  2095.   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
  2096.   "*
  2097. {
  2098.   switch (which_alternative)
  2099.     {
  2100.     case 0:
  2101.       return output_move_quad (operands);
  2102.     case 1:
  2103.       return output_fp_move_quad (operands);
  2104.     case 2:
  2105.       if (TARGET_V9)
  2106.     {
  2107.       operands[1] = adj_offsettable_operand (operands[0], 8);
  2108.       return \"stx %%g0,%0\;stx %%g0,%1\";
  2109.     }
  2110.       else
  2111.     {
  2112.       /* ??? Do we run off the end of the array here? */
  2113.       operands[1] = adj_offsettable_operand (operands[0], 4);
  2114.       operands[2] = adj_offsettable_operand (operands[0], 8);
  2115.       operands[3] = adj_offsettable_operand (operands[0], 12);
  2116.       return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
  2117.     }
  2118.     }
  2119. }"
  2120.   [(set_attr "type" "load,fpload,store")
  2121.    (set_attr "length" "5,5,5")])
  2122.  
  2123. (define_expand "movtf"
  2124.   [(set (match_operand:TF 0 "general_operand" "")
  2125.     (match_operand:TF 1 "general_operand" ""))]
  2126.   ""
  2127.   "
  2128. {
  2129.   if (emit_move_sequence (operands, TFmode))
  2130.     DONE;
  2131. }")
  2132.  
  2133. (define_insn "*movtf_insn"
  2134.   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
  2135.     (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
  2136.   "TARGET_FPU
  2137.    && (register_operand (operands[0], TFmode)
  2138.        || register_operand (operands[1], TFmode))"
  2139.   "*
  2140. {
  2141.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  2142.     return output_fp_move_quad (operands);
  2143.   return output_move_quad (operands);
  2144. }"
  2145.   [(set_attr "type" "fp,move,fpstore,store,fpload,load")
  2146.    (set_attr "length" "4,4,5,5,5,5")])
  2147.  
  2148. ;; Exactly the same as above, except that all `e' cases are deleted.
  2149. ;; This is necessary to prevent reload from ever trying to use a `e' reg
  2150. ;; when -mno-fpu.
  2151.  
  2152. (define_insn "*movtf_no_e_insn"
  2153.   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
  2154.     (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
  2155.   "! TARGET_FPU
  2156.    && (register_operand (operands[0], TFmode)
  2157.        || register_operand (operands[1], TFmode))"
  2158.   "*
  2159. {
  2160.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  2161.     return output_fp_move_quad (operands);
  2162.   return output_move_quad (operands);
  2163. }"
  2164.   [(set_attr "type" "move,store,load")
  2165.    (set_attr "length" "4,5,5")])
  2166.  
  2167. ;; This is disabled because it does not work.  Long doubles have only 8
  2168. ;; byte alignment.  Adding an offset of 8 or 12 to an 8 byte aligned %lo may 
  2169. ;; cause it to overflow.  See also GO_IF_LEGITIMATE_ADDRESS.
  2170. (define_insn "*store_tf"
  2171.   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
  2172.     (match_operand:TF 1 "reg_or_0_operand" "re,G"))
  2173.    (clobber (match_scratch:SI 2 "=&r,&r"))]
  2174.   "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64"
  2175.   "*
  2176. {
  2177.   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
  2178.   if (which_alternative == 0)
  2179.     return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
  2180.   else
  2181.     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
  2182. }"
  2183.   [(set_attr "type" "store")
  2184.    (set_attr "length" "5")])
  2185.  
  2186. ;; Sparc V9 conditional move instructions.
  2187.  
  2188. ;; We can handle larger constants here for some flavors, but for now we play
  2189. ;; it safe and only allow those constants supported by all flavours.
  2190.  
  2191. (define_expand "movsicc"
  2192.   [(set (match_operand:SI 0 "register_operand" "")
  2193.     (if_then_else (match_operand 1 "comparison_operator" "")
  2194.               (match_operand:SI 2 "arith10_operand" "")
  2195.               (match_operand:SI 3 "register_operand" "")))]
  2196.   "TARGET_V9"
  2197.   "
  2198. {
  2199.   enum rtx_code code = GET_CODE (operands[1]);
  2200.  
  2201.   if (sparc_compare_op1 == const0_rtx
  2202.       && GET_CODE (sparc_compare_op0) == REG
  2203.       && GET_MODE (sparc_compare_op0) == DImode
  2204.       && v9_regcmp_p (code))
  2205.     {
  2206.       operands[1] = gen_rtx (code, DImode,
  2207.                  sparc_compare_op0, sparc_compare_op1);
  2208.     }
  2209.   else
  2210.     {
  2211.       rtx cc_reg = gen_compare_reg (code,
  2212.                     sparc_compare_op0, sparc_compare_op1);
  2213.       operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
  2214.     }
  2215. }")
  2216.  
  2217. (define_expand "movdicc"
  2218.   [(set (match_operand:DI 0 "register_operand" "")
  2219.     (if_then_else (match_operand 1 "comparison_operator" "")
  2220.               (match_operand:DI 2 "arith10_operand" "")
  2221.               (match_operand:DI 3 "register_operand" "")))]
  2222.   "TARGET_V9"
  2223.   "
  2224. {
  2225.   enum rtx_code code = GET_CODE (operands[1]);
  2226.  
  2227.   if (sparc_compare_op1 == const0_rtx
  2228.       && GET_CODE (sparc_compare_op0) == REG
  2229.       && GET_MODE (sparc_compare_op0) == DImode
  2230.       && v9_regcmp_p (code))
  2231.     {
  2232.       operands[1] = gen_rtx (code, DImode,
  2233.                  sparc_compare_op0, sparc_compare_op1);
  2234.     }
  2235.   else
  2236.     {
  2237.       rtx cc_reg = gen_compare_reg (code,
  2238.                     sparc_compare_op0, sparc_compare_op1);
  2239.       operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
  2240.     }
  2241. }")
  2242.  
  2243. (define_expand "movsfcc"
  2244.   [(set (match_operand:SF 0 "register_operand" "")
  2245.     (if_then_else (match_operand 1 "comparison_operator" "")
  2246.               (match_operand:SF 2 "register_operand" "")
  2247.               (match_operand:SF 3 "register_operand" "")))]
  2248.   "TARGET_V9"
  2249.   "
  2250. {
  2251.   enum rtx_code code = GET_CODE (operands[1]);
  2252.  
  2253.   if (sparc_compare_op1 == const0_rtx
  2254.       && GET_CODE (sparc_compare_op0) == REG
  2255.       && GET_MODE (sparc_compare_op0) == DImode
  2256.       && v9_regcmp_p (code))
  2257.     {
  2258.       operands[1] = gen_rtx (code, DImode,
  2259.                  sparc_compare_op0, sparc_compare_op1);
  2260.     }
  2261.   else
  2262.     {
  2263.       rtx cc_reg = gen_compare_reg (code,
  2264.                     sparc_compare_op0, sparc_compare_op1);
  2265.       operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
  2266.     }
  2267. }")
  2268.  
  2269. (define_expand "movdfcc"
  2270.   [(set (match_operand:DF 0 "register_operand" "")
  2271.     (if_then_else (match_operand 1 "comparison_operator" "")
  2272.               (match_operand:DF 2 "register_operand" "")
  2273.               (match_operand:DF 3 "register_operand" "")))]
  2274.   "TARGET_V9"
  2275.   "
  2276. {
  2277.   enum rtx_code code = GET_CODE (operands[1]);
  2278.  
  2279.   if (sparc_compare_op1 == const0_rtx
  2280.       && GET_CODE (sparc_compare_op0) == REG
  2281.       && GET_MODE (sparc_compare_op0) == DImode
  2282.       && v9_regcmp_p (code))
  2283.     {
  2284.       operands[1] = gen_rtx (code, DImode,
  2285.                  sparc_compare_op0, sparc_compare_op1);
  2286.     }
  2287.   else
  2288.     {
  2289.       rtx cc_reg = gen_compare_reg (code,
  2290.                     sparc_compare_op0, sparc_compare_op1);
  2291.       operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
  2292.     }
  2293. }")
  2294.  
  2295. (define_expand "movtfcc"
  2296.   [(set (match_operand:TF 0 "register_operand" "")
  2297.     (if_then_else (match_operand 1 "comparison_operator" "")
  2298.               (match_operand:TF 2 "register_operand" "")
  2299.               (match_operand:TF 3 "register_operand" "")))]
  2300.   "TARGET_V9"
  2301.   "
  2302. {
  2303.   enum rtx_code code = GET_CODE (operands[1]);
  2304.  
  2305.   if (sparc_compare_op1 == const0_rtx
  2306.       && GET_CODE (sparc_compare_op0) == REG
  2307.       && GET_MODE (sparc_compare_op0) == DImode
  2308.       && v9_regcmp_p (code))
  2309.     {
  2310.       operands[1] = gen_rtx (code, DImode,
  2311.                  sparc_compare_op0, sparc_compare_op1);
  2312.     }
  2313.   else
  2314.     {
  2315.       rtx cc_reg = gen_compare_reg (code,
  2316.                     sparc_compare_op0, sparc_compare_op1);
  2317.       operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
  2318.     }
  2319. }")
  2320.  
  2321. /* Conditional move define_insns.  */
  2322.  
  2323. (define_insn "*movsi_cc_sp64"
  2324.   [(set (match_operand:SI 0 "register_operand" "=r")
  2325.     (if_then_else (match_operator 1 "comparison_operator"
  2326.                       [(reg:CC 0) (const_int 0)])
  2327.               (match_operand:SI 2 "arith11_operand" "ri")
  2328.               (match_operand:SI 3 "register_operand" "0")))]
  2329.   "TARGET_V9"
  2330.   "mov%C1 %%icc,%2,%0"
  2331.   [(set_attr "type" "cmove")])
  2332.  
  2333. (define_insn "*movdi_cc_sp64"
  2334.   [(set (match_operand:DI 0 "register_operand" "=r")
  2335.     (if_then_else (match_operator 1 "comparison_operator"
  2336.                       [(reg:CC 0) (const_int 0)])
  2337.               (match_operand:DI 2 "arith11_double_operand" "rHI")
  2338.               (match_operand:DI 3 "register_operand" "0")))]
  2339.   "TARGET_V9"
  2340.   "mov%C1 %%icc,%2,%0"
  2341.   [(set_attr "type" "cmove")])
  2342.  
  2343. (define_insn "*movsi_ccx_sp64"
  2344.   [(set (match_operand:SI 0 "register_operand" "=r")
  2345.     (if_then_else (match_operator 1 "comparison_operator"
  2346.                       [(reg:CCX 0) (const_int 0)])
  2347.               (match_operand:SI 2 "arith11_operand" "ri")
  2348.               (match_operand:SI 3 "register_operand" "0")))]
  2349.   "TARGET_V9"
  2350.   "mov%C1 %%xcc,%2,%0"
  2351.   [(set_attr "type" "cmove")])
  2352.  
  2353. (define_insn "*movdi_ccx_sp64"
  2354.   [(set (match_operand:DI 0 "register_operand" "=r")
  2355.     (if_then_else (match_operator 1 "comparison_operator"
  2356.                       [(reg:CCX 0) (const_int 0)])
  2357.               (match_operand:DI 2 "arith11_double_operand" "rHI")
  2358.               (match_operand:DI 3 "register_operand" "0")))]
  2359.   "TARGET_V9"
  2360.   "mov%C1 %%xcc,%2,%0"
  2361.   [(set_attr "type" "cmove")])
  2362.  
  2363. (define_insn "*movsi_ccfp_sp64"
  2364.   [(set (match_operand:SI 0 "register_operand" "=r")
  2365.     (if_then_else (match_operator 1 "comparison_operator"
  2366.                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
  2367.                  (const_int 0)])
  2368.               (match_operand:SI 3 "arith11_operand" "ri")
  2369.               (match_operand:SI 4 "register_operand" "0")))]
  2370.   "TARGET_V9"
  2371.   "mov%C1 %2,%3,%0"
  2372.   [(set_attr "type" "cmove")])
  2373.  
  2374. (define_insn "*movsi_ccfpe_sp64"
  2375.   [(set (match_operand:SI 0 "register_operand" "=r")
  2376.     (if_then_else (match_operator 1 "comparison_operator"
  2377.                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
  2378.                  (const_int 0)])
  2379.               (match_operand:SI 3 "arith11_operand" "ri")
  2380.               (match_operand:SI 4 "register_operand" "0")))]
  2381.   "TARGET_V9"
  2382.   "mov%C1 %2,%3,%0"
  2383.   [(set_attr "type" "cmove")])
  2384.  
  2385. (define_insn "*movdi_ccfp_sp64"
  2386.   [(set (match_operand:DI 0 "register_operand" "=r")
  2387.     (if_then_else (match_operator 1 "comparison_operator"
  2388.                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
  2389.                  (const_int 0)])
  2390.               (match_operand:DI 3 "arith11_double_operand" "rHI")
  2391.               (match_operand:DI 4 "register_operand" "0")))]
  2392.   "TARGET_V9"
  2393.   "mov%C1 %2,%3,%0"
  2394.   [(set_attr "type" "cmove")])
  2395.  
  2396. (define_insn "*movdi_ccfpe_sp64"
  2397.   [(set (match_operand:DI 0 "register_operand" "=r")
  2398.     (if_then_else (match_operator 1 "comparison_operator"
  2399.                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
  2400.                  (const_int 0)])
  2401.               (match_operand:DI 3 "arith11_double_operand" "rHI")
  2402.               (match_operand:DI 4 "register_operand" "0")))]
  2403.   "TARGET_V9"
  2404.   "mov%C1 %2,%3,%0"
  2405.   [(set_attr "type" "cmove")])
  2406.  
  2407. (define_insn "*movsi_cc_reg_sp64"
  2408.   [(set (match_operand:SI 0 "register_operand" "=r")
  2409.     (if_then_else (match_operator 1 "v9_regcmp_op"
  2410.                 [(match_operand:DI 2 "register_operand" "r")
  2411.                  (const_int 0)])
  2412.               (match_operand:SI 3 "arith10_operand" "ri")
  2413.               (match_operand:SI 4 "register_operand" "0")))]
  2414.   "TARGET_V9"
  2415.   "movr%D1 %2,%r3,%0"
  2416.   [(set_attr "type" "cmove")])
  2417.  
  2418. (define_insn "*movdi_cc_reg_sp64"
  2419.   [(set (match_operand:DI 0 "register_operand" "=r")
  2420.     (if_then_else (match_operator 1 "v9_regcmp_op"
  2421.                 [(match_operand:DI 2 "register_operand" "r")
  2422.                  (const_int 0)])
  2423.               (match_operand:DI 3 "arith10_double_operand" "ri")
  2424.               (match_operand:DI 4 "register_operand" "0")))]
  2425.   "TARGET_V9"
  2426.   "movr%D1 %2,%r3,%0"
  2427.   [(set_attr "type" "cmove")])
  2428.  
  2429. (define_insn "*movsf_cc_reg_sp64"
  2430.   [(set (match_operand:SF 0 "register_operand" "=f")
  2431.     (if_then_else (match_operator 1 "v9_regcmp_op"
  2432.                 [(match_operand:DI 2 "register_operand" "r")
  2433.                  (const_int 0)])
  2434.               (match_operand:SF 3 "register_operand" "f")
  2435.               (match_operand:SF 4 "register_operand" "0")))]
  2436.   "TARGET_V9 && TARGET_FPU"
  2437.   "fmovrs%D1 %2,%r3,%0"
  2438.   [(set_attr "type" "cmove")])
  2439.  
  2440. (define_insn "*movdf_cc_reg_sp64"
  2441.   [(set (match_operand:DF 0 "register_operand" "=e")
  2442.     (if_then_else (match_operator 1 "v9_regcmp_op"
  2443.                 [(match_operand:DI 2 "register_operand" "r")
  2444.                  (const_int 0)])
  2445.               (match_operand:DF 3 "register_operand" "e")
  2446.               (match_operand:DF 4 "register_operand" "0")))]
  2447.   "TARGET_V9 && TARGET_FPU"
  2448.   "fmovrd%D1 %2,%r3,%0"
  2449.   [(set_attr "type" "cmove")])
  2450.  
  2451. (define_insn "*movtf_cc_reg_sp64"
  2452.   [(set (match_operand:TF 0 "register_operand" "=e")
  2453.     (if_then_else (match_operator 1 "v9_regcmp_op"
  2454.                 [(match_operand:DI 2 "register_operand" "r")
  2455.                  (const_int 0)])
  2456.               (match_operand:TF 3 "register_operand" "e")
  2457.               (match_operand:TF 4 "register_operand" "0")))]
  2458.   "TARGET_V9 && TARGET_FPU"
  2459.   "fmovrq%D1 %2,%r3,%0"
  2460.   [(set_attr "type" "cmove")])
  2461.  
  2462. (define_insn "*movsf_ccfp_sp64"
  2463.   [(set (match_operand:SF 0 "register_operand" "=f")
  2464.     (if_then_else (match_operator 1 "comparison_operator"
  2465.                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
  2466.                  (const_int 0)])
  2467.               (match_operand:SF 3 "register_operand" "f")
  2468.               (match_operand:SF 4 "register_operand" "0")))]
  2469.   "TARGET_V9 && TARGET_FPU"
  2470.   "fmovs%C1 %2,%3,%0"
  2471.   [(set_attr "type" "cmove")])
  2472.  
  2473. (define_insn "*movsf_ccfpe_sp64"
  2474.   [(set (match_operand:SF 0 "register_operand" "=f")
  2475.     (if_then_else (match_operator 1 "comparison_operator"
  2476.                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
  2477.                  (const_int 0)])
  2478.               (match_operand:SF 3 "register_operand" "f")
  2479.               (match_operand:SF 4 "register_operand" "0")))]
  2480.   "TARGET_V9 && TARGET_FPU"
  2481.   "fmovs%C1 %2,%3,%0"
  2482.   [(set_attr "type" "cmove")])
  2483.  
  2484. (define_insn "*movdf_ccfp_sp64"
  2485.   [(set (match_operand:DF 0 "register_operand" "=e")
  2486.     (if_then_else (match_operator 1 "comparison_operator"
  2487.                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
  2488.                  (const_int 0)])
  2489.               (match_operand:DF 3 "register_operand" "e")
  2490.               (match_operand:DF 4 "register_operand" "0")))]
  2491.   "TARGET_V9 && TARGET_FPU"
  2492.   "fmovd%C1 %2,%3,%0"
  2493.   [(set_attr "type" "cmove")])
  2494.  
  2495. (define_insn "*movdf_ccfpe_sp64"
  2496.   [(set (match_operand:DF 0 "register_operand" "=e")
  2497.     (if_then_else (match_operator 1 "comparison_operator"
  2498.                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
  2499.                  (const_int 0)])
  2500.               (match_operand:DF 3 "register_operand" "e")
  2501.               (match_operand:DF 4 "register_operand" "0")))]
  2502.   "TARGET_V9 && TARGET_FPU"
  2503.   "fmovd%C1 %2,%3,%0"
  2504.   [(set_attr "type" "cmove")])
  2505.  
  2506. (define_insn "*movtf_ccfp_sp64"
  2507.   [(set (match_operand:TF 0 "register_operand" "=e")
  2508.     (if_then_else (match_operator 1 "comparison_operator"
  2509.                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
  2510.                  (const_int 0)])
  2511.               (match_operand:TF 3 "register_operand" "e")
  2512.               (match_operand:TF 4 "register_operand" "0")))]
  2513.   "TARGET_V9 && TARGET_FPU"
  2514.   "fmovq%C1 %2,%3,%0"
  2515.   [(set_attr "type" "cmove")])
  2516.  
  2517. (define_insn "*movtf_ccfpe_sp64"
  2518.   [(set (match_operand:TF 0 "register_operand" "=e")
  2519.     (if_then_else (match_operator 1 "comparison_operator"
  2520.                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
  2521.                  (const_int 0)])
  2522.               (match_operand:TF 3 "register_operand" "e")
  2523.               (match_operand:TF 4 "register_operand" "0")))]
  2524.   "TARGET_V9 && TARGET_FPU"
  2525.   "fmovq%C1 %2,%3,%0"
  2526.   [(set_attr "type" "cmove")])
  2527.  
  2528. (define_insn "*movsf_cc_sp64"
  2529.   [(set (match_operand:SF 0 "register_operand" "=f")
  2530.     (if_then_else (match_operator 1 "comparison_operator"
  2531.                       [(reg:CC 0) (const_int 0)])
  2532.               (match_operand:SF 2 "register_operand" "f")
  2533.               (match_operand:SF 3 "register_operand" "0")))]
  2534.   "TARGET_V9 && TARGET_FPU"
  2535.   "fmovs%C1 %%icc,%2,%0"
  2536.   [(set_attr "type" "cmove")])
  2537.  
  2538. (define_insn "*movdf_cc_sp64"
  2539.   [(set (match_operand:DF 0 "register_operand" "=e")
  2540.     (if_then_else (match_operator 1 "comparison_operator"
  2541.                       [(reg:CC 0) (const_int 0)])
  2542.               (match_operand:DF 2 "register_operand" "e")
  2543.               (match_operand:DF 3 "register_operand" "0")))]
  2544.   "TARGET_V9 && TARGET_FPU"
  2545.   "fmovd%C1 %%icc,%2,%0"
  2546.   [(set_attr "type" "cmove")])
  2547.  
  2548. (define_insn "*movtf_cc_sp64"
  2549.   [(set (match_operand:TF 0 "register_operand" "=e")
  2550.     (if_then_else (match_operator 1 "comparison_operator"
  2551.                       [(reg:CC 0) (const_int 0)])
  2552.               (match_operand:TF 2 "register_operand" "e")
  2553.               (match_operand:TF 3 "register_operand" "0")))]
  2554.   "TARGET_V9 && TARGET_FPU"
  2555.   "fmovq%C1 %%icc,%2,%0"
  2556.   [(set_attr "type" "cmove")])
  2557.  
  2558. (define_insn "*movsf_ccx_sp64"
  2559.   [(set (match_operand:SF 0 "register_operand" "=f")
  2560.     (if_then_else (match_operator 1 "comparison_operator"
  2561.                       [(reg:CCX 0) (const_int 0)])
  2562.               (match_operand:SF 2 "register_operand" "f")
  2563.               (match_operand:SF 3 "register_operand" "0")))]
  2564.   "TARGET_V9 && TARGET_FPU"
  2565.   "fmovs%C1 %%xcc,%2,%0"
  2566.   [(set_attr "type" "cmove")])
  2567.  
  2568. (define_insn "*movdf_ccx_sp64"
  2569.   [(set (match_operand:DF 0 "register_operand" "=e")
  2570.     (if_then_else (match_operator 1 "comparison_operator"
  2571.                       [(reg:CCX 0) (const_int 0)])
  2572.               (match_operand:DF 2 "register_operand" "e")
  2573.               (match_operand:DF 3 "register_operand" "0")))]
  2574.   "TARGET_V9 && TARGET_FPU"
  2575.   "fmovd%C1 %%xcc,%2,%0"
  2576.   [(set_attr "type" "cmove")])
  2577.  
  2578. (define_insn "*movtf_ccx_sp64"
  2579.   [(set (match_operand:TF 0 "register_operand" "=e")
  2580.     (if_then_else (match_operator 1 "comparison_operator"
  2581.                       [(reg:CCX 0) (const_int 0)])
  2582.               (match_operand:TF 2 "register_operand" "e")
  2583.               (match_operand:TF 3 "register_operand" "0")))]
  2584.   "TARGET_V9 && TARGET_FPU"
  2585.   "fmovq%C1 %%xcc,%2,%0"
  2586.   [(set_attr "type" "cmove")])
  2587.  
  2588. ;;- zero extension instructions
  2589.  
  2590. ;; These patterns originally accepted general_operands, however, slightly
  2591. ;; better code is generated by only accepting register_operands, and then
  2592. ;; letting combine generate the ldu[hb] insns.
  2593.  
  2594. (define_expand "zero_extendhisi2"
  2595.   [(set (match_operand:SI 0 "register_operand" "")
  2596.     (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
  2597.   ""
  2598.   "
  2599. {
  2600.   rtx temp = gen_reg_rtx (SImode);
  2601.   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
  2602.   int op1_subword = 0;
  2603.  
  2604.   if (GET_CODE (operand1) == SUBREG)
  2605.     {
  2606.       op1_subword = SUBREG_WORD (operand1);
  2607.       operand1 = XEXP (operand1, 0);
  2608.     }
  2609.  
  2610.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  2611.                      op1_subword),
  2612.               shift_16));
  2613.   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
  2614.   DONE;
  2615. }")
  2616.  
  2617. (define_insn "*zero_extendhisi2_insn"
  2618.   [(set (match_operand:SI 0 "register_operand" "=r")
  2619.     (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  2620.   ""
  2621.   "lduh %1,%0"
  2622.   [(set_attr "type" "load")])
  2623.  
  2624. (define_expand "zero_extendqihi2"
  2625.   [(set (match_operand:HI 0 "register_operand" "")
  2626.     (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
  2627.   ""
  2628.   "")
  2629.  
  2630. (define_insn "*zero_extendqihi2_insn"
  2631.   [(set (match_operand:HI 0 "register_operand" "=r,r")
  2632.     (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
  2633.   "GET_CODE (operands[1]) != CONST_INT"
  2634.   "@
  2635.    and %1,0xff,%0
  2636.    ldub %1,%0"
  2637.   [(set_attr "type" "unary,load")
  2638.    (set_attr "length" "1")])
  2639.  
  2640. (define_expand "zero_extendqisi2"
  2641.   [(set (match_operand:SI 0 "register_operand" "")
  2642.     (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
  2643.   ""
  2644.   "")
  2645.  
  2646. (define_insn "*zero_extendqisi2_insn"
  2647.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  2648.     (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
  2649.   "GET_CODE (operands[1]) != CONST_INT"
  2650.   "@
  2651.    and %1,0xff,%0
  2652.    ldub %1,%0"
  2653.   [(set_attr "type" "unary,load")
  2654.    (set_attr "length" "1")])
  2655.  
  2656. (define_expand "zero_extendqidi2"
  2657.   [(set (match_operand:DI 0 "register_operand" "")
  2658.     (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
  2659.   "TARGET_V9"
  2660.   "")
  2661.  
  2662. (define_insn "*zero_extendqidi2_insn"
  2663.   [(set (match_operand:DI 0 "register_operand" "=r,r")
  2664.     (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
  2665.   "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
  2666.   "@
  2667.    and %1,0xff,%0
  2668.    ldub %1,%0"
  2669.   [(set_attr "type" "unary,load")
  2670.    (set_attr "length" "1")])
  2671.  
  2672. (define_expand "zero_extendhidi2"
  2673.   [(set (match_operand:DI 0 "register_operand" "")
  2674.     (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
  2675.   "TARGET_V9"
  2676.   "
  2677. {
  2678.   rtx temp = gen_reg_rtx (DImode);
  2679.   rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
  2680.   int op1_subword = 0;
  2681.  
  2682.   if (GET_CODE (operand1) == SUBREG)
  2683.     {
  2684.       op1_subword = SUBREG_WORD (operand1);
  2685.       operand1 = XEXP (operand1, 0);
  2686.     }
  2687.  
  2688.   emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
  2689.                      op1_subword),
  2690.               shift_48));
  2691.   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
  2692.   DONE;
  2693. }")
  2694.  
  2695. (define_insn "*zero_extendhidi2_insn"
  2696.   [(set (match_operand:DI 0 "register_operand" "=r")
  2697.     (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
  2698.   "TARGET_V9"
  2699.   "lduh %1,%0"
  2700.   [(set_attr "type" "load")])
  2701.  
  2702. ;; ??? Write truncdisi pattern using sra?
  2703.  
  2704. (define_expand "zero_extendsidi2"
  2705.   [(set (match_operand:DI 0 "register_operand" "")
  2706.     (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
  2707.   "TARGET_V9"
  2708.   "")
  2709.  
  2710. (define_insn "*zero_extendsidi2_insn"
  2711.   [(set (match_operand:DI 0 "register_operand" "=r,r")
  2712.     (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
  2713.   "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
  2714.   "@
  2715.    srl %1,0,%0
  2716.    lduw %1,%0"
  2717.   [(set_attr "type" "unary,load")
  2718.    (set_attr "length" "1")])
  2719.  
  2720. ;; Simplify comparisons of extended values.
  2721.  
  2722. (define_insn "*cmp_zero_extendqisi2"
  2723.   [(set (reg:CC 0)
  2724.     (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
  2725.             (const_int 0)))]
  2726.   ""
  2727.   "andcc %0,0xff,%%g0"
  2728.   [(set_attr "type" "compare")])
  2729.  
  2730. (define_insn "*cmp_zero_extendqisi2_set"
  2731.   [(set (reg:CC 0)
  2732.     (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
  2733.             (const_int 0)))
  2734.    (set (match_operand:SI 0 "register_operand" "=r")
  2735.     (zero_extend:SI (match_dup 1)))]
  2736.   ""
  2737.   "andcc %1,0xff,%0"
  2738.   [(set_attr "type" "unary")])
  2739.  
  2740. ;; Similarly, handle SI->QI mode truncation followed by a compare.
  2741.  
  2742. (define_insn "*cmp_siqi_trunc"
  2743.   [(set (reg:CC 0)
  2744.     (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
  2745.             (const_int 0)))]
  2746.   ""
  2747.   "andcc %0,0xff,%%g0"
  2748.   [(set_attr "type" "compare")])
  2749.  
  2750. (define_insn "*cmp_siqi_trunc_set"
  2751.   [(set (reg:CC 0)
  2752.     (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
  2753.             (const_int 0)))
  2754.    (set (match_operand:QI 0 "register_operand" "=r")
  2755.     (match_dup 1))]
  2756.   ""
  2757.   "andcc %1,0xff,%0"
  2758.   [(set_attr "type" "unary")])
  2759.  
  2760. ;;- sign extension instructions
  2761.  
  2762. ;; These patterns originally accepted general_operands, however, slightly
  2763. ;; better code is generated by only accepting register_operands, and then
  2764. ;; letting combine generate the lds[hb] insns.
  2765.  
  2766. (define_expand "extendhisi2"
  2767.   [(set (match_operand:SI 0 "register_operand" "")
  2768.     (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
  2769.   ""
  2770.   "
  2771. {
  2772.   rtx temp = gen_reg_rtx (SImode);
  2773.   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
  2774.   int op1_subword = 0;
  2775.  
  2776.   if (GET_CODE (operand1) == SUBREG)
  2777.     {
  2778.       op1_subword = SUBREG_WORD (operand1);
  2779.       operand1 = XEXP (operand1, 0);
  2780.     }
  2781.  
  2782.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  2783.                      op1_subword),
  2784.               shift_16));
  2785.   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
  2786.   DONE;
  2787. }")
  2788.  
  2789. (define_insn "*sign_extendhisi2_insn"
  2790.   [(set (match_operand:SI 0 "register_operand" "=r")
  2791.     (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  2792.   ""
  2793.   "ldsh %1,%0"
  2794.   [(set_attr "type" "load")])
  2795.  
  2796. (define_expand "extendqihi2"
  2797.   [(set (match_operand:HI 0 "register_operand" "")
  2798.     (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
  2799.   ""
  2800.   "
  2801. {
  2802.   rtx temp = gen_reg_rtx (SImode);
  2803.   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
  2804.   int op1_subword = 0;
  2805.   int op0_subword = 0;
  2806.  
  2807.   if (GET_CODE (operand1) == SUBREG)
  2808.     {
  2809.       op1_subword = SUBREG_WORD (operand1);
  2810.       operand1 = XEXP (operand1, 0);
  2811.     }
  2812.   if (GET_CODE (operand0) == SUBREG)
  2813.     {
  2814.       op0_subword = SUBREG_WORD (operand0);
  2815.       operand0 = XEXP (operand0, 0);
  2816.     }
  2817.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  2818.                      op1_subword),
  2819.               shift_24));
  2820.   if (GET_MODE (operand0) != SImode)
  2821.     operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
  2822.   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
  2823.   DONE;
  2824. }")
  2825.  
  2826. (define_insn "*sign_extendqihi2_insn"
  2827.   [(set (match_operand:HI 0 "register_operand" "=r")
  2828.     (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
  2829.   ""
  2830.   "ldsb %1,%0"
  2831.   [(set_attr "type" "load")])
  2832.  
  2833. (define_expand "extendqisi2"
  2834.   [(set (match_operand:SI 0 "register_operand" "")
  2835.     (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
  2836.   ""
  2837.   "
  2838. {
  2839.   rtx temp = gen_reg_rtx (SImode);
  2840.   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
  2841.   int op1_subword = 0;
  2842.  
  2843.   if (GET_CODE (operand1) == SUBREG)
  2844.     {
  2845.       op1_subword = SUBREG_WORD (operand1);
  2846.       operand1 = XEXP (operand1, 0);
  2847.     }
  2848.  
  2849.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  2850.                      op1_subword),
  2851.               shift_24));
  2852.   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
  2853.   DONE;
  2854. }")
  2855.  
  2856. (define_insn "*sign_extendqisi2_insn"
  2857.   [(set (match_operand:SI 0 "register_operand" "=r")
  2858.     (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
  2859.   ""
  2860.   "ldsb %1,%0"
  2861.   [(set_attr "type" "load")])
  2862.  
  2863. (define_expand "extendqidi2"
  2864.   [(set (match_operand:DI 0 "register_operand" "")
  2865.     (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
  2866.   "TARGET_V9"
  2867.   "
  2868. {
  2869.   rtx temp = gen_reg_rtx (DImode);
  2870.   rtx shift_56 = gen_rtx (CONST_INT, VOIDmode, 56);
  2871.   int op1_subword = 0;
  2872.  
  2873.   if (GET_CODE (operand1) == SUBREG)
  2874.     {
  2875.       op1_subword = SUBREG_WORD (operand1);
  2876.       operand1 = XEXP (operand1, 0);
  2877.     }
  2878.  
  2879.   emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
  2880.                      op1_subword),
  2881.               shift_56));
  2882.   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
  2883.   DONE;
  2884. }")
  2885.  
  2886. (define_insn "*sign_extendqidi2_insn"
  2887.   [(set (match_operand:DI 0 "register_operand" "=r")
  2888.     (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
  2889.   "TARGET_V9"
  2890.   "ldsb %1,%0"
  2891.   [(set_attr "type" "load")])
  2892.  
  2893. (define_expand "extendhidi2"
  2894.   [(set (match_operand:DI 0 "register_operand" "")
  2895.     (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
  2896.   "TARGET_V9"
  2897.   "
  2898. {
  2899.   rtx temp = gen_reg_rtx (DImode);
  2900.   rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
  2901.   int op1_subword = 0;
  2902.  
  2903.   if (GET_CODE (operand1) == SUBREG)
  2904.     {
  2905.       op1_subword = SUBREG_WORD (operand1);
  2906.       operand1 = XEXP (operand1, 0);
  2907.     }
  2908.  
  2909.   emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
  2910.                      op1_subword),
  2911.               shift_48));
  2912.   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
  2913.   DONE;
  2914. }")
  2915.  
  2916. (define_insn "*sign_extendhidi2_insn"
  2917.   [(set (match_operand:DI 0 "register_operand" "=r")
  2918.     (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
  2919.   "TARGET_V9"
  2920.   "ldsh %1,%0"
  2921.   [(set_attr "type" "load")])
  2922.  
  2923. (define_expand "extendsidi2"
  2924.   [(set (match_operand:DI 0 "register_operand" "")
  2925.     (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
  2926.   "TARGET_V9"
  2927.   "")
  2928.  
  2929. (define_insn "*sign_extendsidi2_insn"
  2930.   [(set (match_operand:DI 0 "register_operand" "=r,r")
  2931.     (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
  2932.   "TARGET_V9"
  2933.   "@
  2934.   sra %1,0,%0
  2935.   ldsw %1,%0"
  2936.   [(set_attr "type" "unary,load")
  2937.    (set_attr "length" "1")])
  2938.  
  2939. ;; Special pattern for optimizing bit-field compares.  This is needed
  2940. ;; because combine uses this as a canonical form.
  2941.  
  2942. (define_insn "*cmp_zero_extract"
  2943.   [(set (reg:CC 0)
  2944.     (compare:CC
  2945.      (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
  2946.               (match_operand:SI 1 "small_int" "n")
  2947.               (match_operand:SI 2 "small_int" "n"))
  2948.      (const_int 0)))]
  2949.   "INTVAL (operands[2]) > 19"
  2950.   "*
  2951. {
  2952.   int len = INTVAL (operands[1]);
  2953.   int pos = 32 - INTVAL (operands[2]) - len;
  2954.   unsigned mask = ((1 << len) - 1) << pos;
  2955.  
  2956.   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
  2957.   return \"andcc %0,%1,%%g0\";
  2958. }")
  2959.  
  2960. (define_insn "*cmp_zero_extract_sp64"
  2961.   [(set (reg:CCX 0)
  2962.     (compare:CCX
  2963.      (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
  2964.               (match_operand:SI 1 "small_int" "n")
  2965.               (match_operand:SI 2 "small_int" "n"))
  2966.      (const_int 0)))]
  2967.   "TARGET_V9 && INTVAL (operands[2]) > 51"
  2968.   "*
  2969. {
  2970.   int len = INTVAL (operands[1]);
  2971.   int pos = 64 - INTVAL (operands[2]) - len;
  2972.   unsigned mask = ((1 << len) - 1) << pos;
  2973.  
  2974.   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
  2975.   return \"andcc %0,%1,%%g0\";
  2976. }")
  2977.  
  2978. ;; Conversions between float, double and long double.
  2979.  
  2980. (define_insn "extendsfdf2"
  2981.   [(set (match_operand:DF 0 "register_operand" "=e")
  2982.     (float_extend:DF
  2983.      (match_operand:SF 1 "register_operand" "f")))]
  2984.   "TARGET_FPU"
  2985.   "fstod %1,%0"
  2986.   [(set_attr "type" "fp")])
  2987.  
  2988. (define_insn "extendsftf2"
  2989.   [(set (match_operand:TF 0 "register_operand" "=e")
  2990.     (float_extend:TF
  2991.      (match_operand:SF 1 "register_operand" "f")))]
  2992.   "TARGET_FPU && TARGET_HARD_QUAD"
  2993.   "fstoq %1,%0"
  2994.   [(set_attr "type" "fp")])
  2995.  
  2996. (define_insn "extenddftf2"
  2997.   [(set (match_operand:TF 0 "register_operand" "=e")
  2998.     (float_extend:TF
  2999.      (match_operand:DF 1 "register_operand" "e")))]
  3000.   "TARGET_FPU && TARGET_HARD_QUAD"
  3001.   "fdtoq %1,%0"
  3002.   [(set_attr "type" "fp")])
  3003.  
  3004. (define_insn "truncdfsf2"
  3005.   [(set (match_operand:SF 0 "register_operand" "=f")
  3006.     (float_truncate:SF
  3007.      (match_operand:DF 1 "register_operand" "e")))]
  3008.   "TARGET_FPU"
  3009.   "fdtos %1,%0"
  3010.   [(set_attr "type" "fp")])
  3011.  
  3012. (define_insn "trunctfsf2"
  3013.   [(set (match_operand:SF 0 "register_operand" "=f")
  3014.     (float_truncate:SF
  3015.      (match_operand:TF 1 "register_operand" "e")))]
  3016.   "TARGET_FPU && TARGET_HARD_QUAD"
  3017.   "fqtos %1,%0"
  3018.   [(set_attr "type" "fp")])
  3019.  
  3020. (define_insn "trunctfdf2"
  3021.   [(set (match_operand:DF 0 "register_operand" "=e")
  3022.     (float_truncate:DF
  3023.      (match_operand:TF 1 "register_operand" "e")))]
  3024.   "TARGET_FPU && TARGET_HARD_QUAD"
  3025.   "fqtod %1,%0"
  3026.   [(set_attr "type" "fp")])
  3027.  
  3028. ;; Conversion between fixed point and floating point.
  3029.  
  3030. (define_insn "floatsisf2"
  3031.   [(set (match_operand:SF 0 "register_operand" "=f")
  3032.     (float:SF (match_operand:SI 1 "register_operand" "f")))]
  3033.   "TARGET_FPU"
  3034.   "fitos %1,%0"
  3035.   [(set_attr "type" "fp")])
  3036.  
  3037. (define_insn "floatsidf2"
  3038.   [(set (match_operand:DF 0 "register_operand" "=e")
  3039.     (float:DF (match_operand:SI 1 "register_operand" "f")))]
  3040.   "TARGET_FPU"
  3041.   "fitod %1,%0"
  3042.   [(set_attr "type" "fp")])
  3043.  
  3044. (define_insn "floatsitf2"
  3045.   [(set (match_operand:TF 0 "register_operand" "=e")
  3046.     (float:TF (match_operand:SI 1 "register_operand" "f")))]
  3047.   "TARGET_FPU && TARGET_HARD_QUAD"
  3048.   "fitoq %1,%0"
  3049.   [(set_attr "type" "fp")])
  3050.  
  3051. ;; Now the same for 64 bit sources.
  3052. ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
  3053.  
  3054. (define_expand "floatdisf2"
  3055.   [(parallel [(set (match_operand:SF 0 "register_operand" "")
  3056.            (float:SF (match_operand:DI 1 "general_operand" "")))
  3057.           (clobber (match_dup 2))
  3058.           (clobber (match_dup 3))])]
  3059.   "TARGET_V9 && TARGET_FPU"
  3060.   "
  3061. {
  3062.   operands[2] = gen_reg_rtx (DFmode);
  3063.   operands[3] = sparc64_fpconv_stack_temp ();
  3064. }")
  3065.  
  3066. (define_expand "floatdidf2"
  3067.   [(parallel [(set (match_operand:DF 0 "register_operand" "")
  3068.            (float:DF (match_operand:DI 1 "general_operand" "")))
  3069.           (clobber (match_dup 2))
  3070.           (clobber (match_dup 3))])]
  3071.   "TARGET_V9 && TARGET_FPU"
  3072.   "
  3073. {
  3074.   operands[2] = gen_reg_rtx (DFmode);
  3075.   operands[3] = sparc64_fpconv_stack_temp ();
  3076. }")
  3077.  
  3078. (define_expand "floatditf2"
  3079.   [(parallel [(set (match_operand:TF 0 "register_operand" "")
  3080.            (float:TF (match_operand:DI 1 "general_operand" "")))
  3081.           (clobber (match_dup 2))
  3082.           (clobber (match_dup 3))])]
  3083.   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  3084.   "
  3085. {
  3086.   operands[2] = gen_reg_rtx (DFmode);
  3087.   operands[3] = sparc64_fpconv_stack_temp ();
  3088. }")
  3089.  
  3090. (define_insn "*floatdisf2_insn"
  3091.   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
  3092.            (float:SF (match_operand:DI 1 "general_operand" "rm")))
  3093.           (clobber (match_operand:DF 2 "register_operand" "=&e"))
  3094.           (clobber (match_operand:DI 3 "memory_operand" "m"))])]
  3095.   "TARGET_V9 && TARGET_FPU"
  3096.   "*
  3097. {
  3098.   if (GET_CODE (operands[1]) == MEM)
  3099.     output_asm_insn (\"ldd %1,%2\", operands);
  3100.   else
  3101.     output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
  3102.   return \"fxtos %2,%0\";
  3103. }"
  3104.   [(set_attr "type" "fp")
  3105.    (set_attr "length" "3")])
  3106.  
  3107. (define_insn "*floatdidf2_insn"
  3108.   [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
  3109.            (float:DF (match_operand:DI 1 "general_operand" "rm")))
  3110.           (clobber (match_operand:DF 2 "register_operand" "=&e"))
  3111.           (clobber (match_operand:DI 3 "memory_operand" "m"))])]
  3112.   "TARGET_V9 && TARGET_FPU"
  3113.   "*
  3114. {
  3115.   if (GET_CODE (operands[1]) == MEM)
  3116.     output_asm_insn (\"ldd %1,%2\", operands);
  3117.   else
  3118.     output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
  3119.   return \"fxtod %2,%0\";
  3120. }"
  3121.   [(set_attr "type" "fp")
  3122.    (set_attr "length" "3")])
  3123.  
  3124. (define_insn "*floatditf2_insn"
  3125.   [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
  3126.            (float:TF (match_operand:DI 1 "general_operand" "rm")))
  3127.           (clobber (match_operand:DF 2 "register_operand" "=&e"))
  3128.           (clobber (match_operand:DI 3 "memory_operand" "m"))])]
  3129.   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  3130.   "*
  3131. {
  3132.   if (GET_CODE (operands[1]) == MEM)
  3133.     output_asm_insn (\"ldd %1,%2\", operands);
  3134.   else
  3135.     output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
  3136.   return \"fxtoq %2,%0\";
  3137. }"
  3138.   [(set_attr "type" "fp")
  3139.    (set_attr "length" "3")])
  3140.  
  3141. ;; ??? Ideally, these are what we would like to use.
  3142.  
  3143. (define_insn "floatdisf2_sp64"
  3144.   [(set (match_operand:SF 0 "register_operand" "=f")
  3145.     (float:SF (match_operand:DI 1 "register_operand" "e")))]
  3146.   "0 && TARGET_V9 && TARGET_FPU"
  3147.   "fxtos %1,%0"
  3148.   [(set_attr "type" "fp")])
  3149.  
  3150. (define_insn "floatdidf2_sp64"
  3151.   [(set (match_operand:DF 0 "register_operand" "=e")
  3152.     (float:DF (match_operand:DI 1 "register_operand" "e")))]
  3153.   "0 && TARGET_V9 && TARGET_FPU"
  3154.   "fxtod %1,%0"
  3155.   [(set_attr "type" "fp")])
  3156.  
  3157. (define_insn "floatditf2_sp64"
  3158.   [(set (match_operand:TF 0 "register_operand" "=e")
  3159.     (float:TF (match_operand:DI 1 "register_operand" "e")))]
  3160.   "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  3161.   "fxtoq %1,%0"
  3162.   [(set_attr "type" "fp")])
  3163.  
  3164. ;; Convert a float to an actual integer.
  3165. ;; Truncation is performed as part of the conversion.
  3166.  
  3167. (define_insn "fix_truncsfsi2"
  3168.   [(set (match_operand:SI 0 "register_operand" "=f")
  3169.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
  3170.   "TARGET_FPU"
  3171.   "fstoi %1,%0"
  3172.   [(set_attr "type" "fp")])
  3173.  
  3174. (define_insn "fix_truncdfsi2"
  3175.   [(set (match_operand:SI 0 "register_operand" "=f")
  3176.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
  3177.   "TARGET_FPU"
  3178.   "fdtoi %1,%0"
  3179.   [(set_attr "type" "fp")])
  3180.  
  3181. (define_insn "fix_trunctfsi2"
  3182.   [(set (match_operand:SI 0 "register_operand" "=f")
  3183.     (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
  3184.   "TARGET_FPU && TARGET_HARD_QUAD"
  3185.   "fqtoi %1,%0"
  3186.   [(set_attr "type" "fp")])
  3187.  
  3188. ;; Now the same, for 64-bit targets
  3189. ;; ??? We try to work around an interesting problem.
  3190. ;; If gcc tries to do a subreg on the result it will get the wrong answer:
  3191. ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
  3192. ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
  3193. ;; the "0" to a "1".  One could enhance alter_subreg but it is not clear how to
  3194. ;; do this cleanly.
  3195.  
  3196. (define_expand "fix_truncsfdi2"
  3197.   [(parallel [(set (match_operand:DI 0 "general_operand" "")
  3198.            (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
  3199.           (clobber (match_dup 2))
  3200.           (clobber (match_dup 3))])]
  3201.   "TARGET_V9 && TARGET_FPU"
  3202.   "
  3203. {
  3204.   operands[2] = gen_reg_rtx (DFmode);
  3205.   operands[3] = sparc64_fpconv_stack_temp ();
  3206. }")
  3207.  
  3208. (define_expand "fix_truncdfdi2"
  3209.   [(parallel [(set (match_operand:DI 0 "general_operand" "")
  3210.            (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
  3211.           (clobber (match_dup 2))
  3212.           (clobber (match_dup 3))])]
  3213.   "TARGET_V9 && TARGET_FPU"
  3214.   "
  3215. {
  3216.   operands[2] = gen_reg_rtx (DFmode);
  3217.   operands[3] = sparc64_fpconv_stack_temp ();
  3218. }")
  3219.  
  3220. (define_expand "fix_trunctfdi2"
  3221.   [(parallel [(set (match_operand:DI 0 "general_operand" "")
  3222.            (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
  3223.           (clobber (match_dup 2))
  3224.           (clobber (match_dup 3))])]
  3225.   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  3226.   "
  3227. {
  3228.   operands[2] = gen_reg_rtx (DFmode);
  3229.   operands[3] = sparc64_fpconv_stack_temp ();
  3230. }")
  3231.  
  3232. (define_insn "*fix_truncsfdi2_insn"
  3233.   [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
  3234.            (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  3235.           (clobber (match_operand:DF 2 "register_operand" "=&e"))
  3236.           (clobber (match_operand:DI 3 "memory_operand" "m"))])]
  3237.   "TARGET_V9 && TARGET_FPU"
  3238.   "*
  3239. {
  3240.   output_asm_insn (\"fstox %1,%2\", operands);
  3241.   if (GET_CODE (operands[0]) == MEM)
  3242.     return \"std %2,%0\";
  3243.   else
  3244.     return \"std %2,%3\;ldx %3,%0\";
  3245. }"
  3246.   [(set_attr "type" "fp")
  3247.    (set_attr "length" "3")])
  3248.  
  3249. (define_insn "*fix_truncdfdi2_insn"
  3250.   [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
  3251.            (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
  3252.           (clobber (match_operand:DF 2 "register_operand" "=&e"))
  3253.           (clobber (match_operand:DI 3 "memory_operand" "m"))])]
  3254.   "TARGET_V9 && TARGET_FPU"
  3255.   "*
  3256. {
  3257.   output_asm_insn (\"fdtox %1,%2\", operands);
  3258.   if (GET_CODE (operands[0]) == MEM)
  3259.     return \"std %2,%0\";
  3260.   else
  3261.     return \"std %2,%3\;ldx %3,%0\";
  3262. }"
  3263.   [(set_attr "type" "fp")
  3264.    (set_attr "length" "3")])
  3265.  
  3266. (define_insn "*fix_trunctfdi2_insn"
  3267.   [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
  3268.            (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
  3269.           (clobber (match_operand:DF 2 "register_operand" "=&e"))
  3270.           (clobber (match_operand:DI 3 "memory_operand" "m"))])]
  3271.   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  3272.   "*
  3273. {
  3274.   output_asm_insn (\"fqtox %1,%2\", operands);
  3275.   if (GET_CODE (operands[0]) == MEM)
  3276.     return \"std %2,%0\";
  3277.   else
  3278.     return \"std %2,%3\;ldx %3,%0\";
  3279. }"
  3280.   [(set_attr "type" "fp")
  3281.    (set_attr "length" "3")])
  3282.  
  3283. ;; ??? Ideally, these are what we would like to use.
  3284.  
  3285. (define_insn "fix_truncsfdi2_sp64"
  3286.   [(set (match_operand:DI 0 "register_operand" "=e")
  3287.     (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
  3288.   "0 && TARGET_V9 && TARGET_FPU"
  3289.   "fstox %1,%0"
  3290.   [(set_attr "type" "fp")])
  3291.  
  3292. (define_insn "fix_truncdfdi2_sp64"
  3293.   [(set (match_operand:DI 0 "register_operand" "=e")
  3294.     (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
  3295.   "0 && TARGET_V9 && TARGET_FPU"
  3296.   "fdtox %1,%0"
  3297.   [(set_attr "type" "fp")])
  3298.  
  3299. (define_insn "fix_trunctfdi2_sp64"
  3300.   [(set (match_operand:DI 0 "register_operand" "=e")
  3301.     (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
  3302.   "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
  3303.   "fqtox %1,%0"
  3304.   [(set_attr "type" "fp")])
  3305.  
  3306. ;;- arithmetic instructions
  3307.  
  3308. (define_expand "adddi3"
  3309.   [(set (match_operand:DI 0 "register_operand" "=r")
  3310.     (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3311.          (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3312.   ""
  3313.   "
  3314. {
  3315.   if (! TARGET_V9)
  3316.     {
  3317.       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  3318.               gen_rtx (SET, VOIDmode, operands[0],
  3319.                    gen_rtx (PLUS, DImode, operands[1],
  3320.                           operands[2])),
  3321.               gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
  3322.       DONE;
  3323.     }
  3324. }")
  3325.  
  3326. (define_insn "*adddi3_sp32"
  3327.   [(set (match_operand:DI 0 "register_operand" "=r")
  3328.     (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3329.          (match_operand:DI 2 "arith_double_operand" "rHI")))
  3330.    (clobber (reg:SI 0))]
  3331.   "! TARGET_V9"
  3332.   "*
  3333. {
  3334.   rtx op2 = operands[2];
  3335.  
  3336.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  3337.      Give the assembler a chance to pick the move instruction. */
  3338.   if (GET_CODE (op2) == CONST_INT)
  3339.     {
  3340.       int sign = INTVAL (op2);
  3341.       if (sign < 0)
  3342.     return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
  3343.       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
  3344.     }
  3345.   else if (GET_CODE (op2) == CONST_DOUBLE)
  3346.     {
  3347.       rtx xoperands[4];
  3348.       xoperands[0] = operands[0];
  3349.       xoperands[1] = operands[1];
  3350.       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
  3351.       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
  3352.       if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
  3353.     output_asm_insn (\"add %1,%3,%0\", xoperands);
  3354.       else
  3355.     output_asm_insn (\"addcc %R1,%2,%R0\;addx %1,%3,%0\", xoperands);
  3356.       return \"\";
  3357.     }
  3358.   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
  3359. }"
  3360.   [(set_attr "length" "2")])
  3361.  
  3362. (define_insn "*adddi3_sp64"
  3363.   [(set (match_operand:DI 0 "register_operand" "=r")
  3364.     (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3365.          (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3366.   "TARGET_V9"
  3367.   "add %1,%2,%0")
  3368.  
  3369. (define_insn "addsi3"
  3370.   [(set (match_operand:SI 0 "register_operand" "=r")
  3371.     (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  3372.          (match_operand:SI 2 "arith_operand" "rI")))]
  3373.   ""
  3374.   "add %1,%2,%0"
  3375.   [(set_attr "type" "ialu")])
  3376.  
  3377. (define_insn "*cmp_cc_plus"
  3378.   [(set (reg:CC_NOOV 0)
  3379.     (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
  3380.                   (match_operand:SI 1 "arith_operand" "rI"))
  3381.              (const_int 0)))]
  3382.   ""
  3383.   "addcc %0,%1,%%g0"
  3384.   [(set_attr "type" "compare")])
  3385.  
  3386. (define_insn "*cmp_ccx_plus"
  3387.   [(set (reg:CCX_NOOV 0)
  3388.     (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
  3389.                    (match_operand:DI 1 "arith_double_operand" "rHI"))
  3390.               (const_int 0)))]
  3391.   "TARGET_V9"
  3392.   "addcc %0,%1,%%g0"
  3393.   [(set_attr "type" "compare")])
  3394.  
  3395. (define_insn "*cmp_cc_plus_set"
  3396.   [(set (reg:CC_NOOV 0)
  3397.     (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  3398.                   (match_operand:SI 2 "arith_operand" "rI"))
  3399.              (const_int 0)))
  3400.    (set (match_operand:SI 0 "register_operand" "=r")
  3401.     (plus:SI (match_dup 1) (match_dup 2)))]
  3402.   ""
  3403.   "addcc %1,%2,%0")
  3404.  
  3405. (define_insn "*cmp_ccx_plus_set"
  3406.   [(set (reg:CCX_NOOV 0)
  3407.     (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3408.                    (match_operand:DI 2 "arith_double_operand" "rHI"))
  3409.               (const_int 0)))
  3410.    (set (match_operand:DI 0 "register_operand" "=r")
  3411.     (plus:DI (match_dup 1) (match_dup 2)))]
  3412.   "TARGET_V9"
  3413.   "addcc %1,%2,%0")
  3414.  
  3415. (define_expand "subdi3"
  3416.   [(set (match_operand:DI 0 "register_operand" "=r")
  3417.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  3418.           (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3419.   ""
  3420.   "
  3421. {
  3422.   if (! TARGET_V9)
  3423.     {
  3424.       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  3425.               gen_rtx (SET, VOIDmode, operands[0],
  3426.                    gen_rtx (MINUS, DImode, operands[1],
  3427.                            operands[2])),
  3428.               gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
  3429.       DONE;
  3430.     }
  3431. }")
  3432.  
  3433. (define_insn "*subdi3_sp32"
  3434.   [(set (match_operand:DI 0 "register_operand" "=r")
  3435.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  3436.           (match_operand:DI 2 "arith_double_operand" "rHI")))
  3437.    (clobber (reg:SI 0))]
  3438.   "! TARGET_V9"
  3439.   "*
  3440. {
  3441.   rtx op2 = operands[2];
  3442.  
  3443.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  3444.      Give the assembler a chance to pick the move instruction. */
  3445.   if (GET_CODE (op2) == CONST_INT)
  3446.     {
  3447.       int sign = INTVAL (op2);
  3448.       if (sign < 0)
  3449.     return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
  3450.       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
  3451.     }
  3452.   else if (GET_CODE (op2) == CONST_DOUBLE)
  3453.     {
  3454.       rtx xoperands[4];
  3455.       xoperands[0] = operands[0];
  3456.       xoperands[1] = operands[1];
  3457.       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
  3458.       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
  3459.       if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
  3460.     output_asm_insn (\"sub %1,%3,%0\", xoperands);
  3461.       else
  3462.     output_asm_insn (\"subcc %R1,%2,%R0\;subx %1,%3,%0\", xoperands);
  3463.       return \"\";
  3464.     }
  3465.   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
  3466. }"
  3467.   [(set_attr "length" "2")])
  3468.  
  3469. (define_insn "*subdi3_sp64"
  3470.   [(set (match_operand:DI 0 "register_operand" "=r")
  3471.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  3472.           (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3473.   "TARGET_V9"
  3474.   "sub %1,%2,%0")
  3475.  
  3476. (define_insn "subsi3"
  3477.   [(set (match_operand:SI 0 "register_operand" "=r")
  3478.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  3479.           (match_operand:SI 2 "arith_operand" "rI")))]
  3480.   ""
  3481.   "sub %1,%2,%0"
  3482.   [(set_attr "type" "ialu")])
  3483.  
  3484. (define_insn "*cmp_minus_cc"
  3485.   [(set (reg:CC_NOOV 0)
  3486.     (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
  3487.                    (match_operand:SI 1 "arith_operand" "rI"))
  3488.              (const_int 0)))]
  3489.   ""
  3490.   "subcc %0,%1,%%g0"
  3491.   [(set_attr "type" "compare")])
  3492.  
  3493. (define_insn "*cmp_minus_ccx"
  3494.   [(set (reg:CCX_NOOV 0)
  3495.     (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
  3496.                     (match_operand:DI 1 "arith_double_operand" "rHI"))
  3497.               (const_int 0)))]
  3498.   "TARGET_V9"
  3499.   "subcc %0,%1,%%g0"
  3500.   [(set_attr "type" "compare")])
  3501.  
  3502. (define_insn "*cmp_minus_cc_set"
  3503.   [(set (reg:CC_NOOV 0)
  3504.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
  3505.                    (match_operand:SI 2 "arith_operand" "rI"))
  3506.              (const_int 0)))
  3507.    (set (match_operand:SI 0 "register_operand" "=r")
  3508.     (minus:SI (match_dup 1) (match_dup 2)))]
  3509.   ""
  3510.   "subcc %1,%2,%0")
  3511.  
  3512. (define_insn "*cmp_minus_ccx_set"
  3513.   [(set (reg:CCX_NOOV 0)
  3514.     (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
  3515.                     (match_operand:DI 2 "arith_double_operand" "rHI"))
  3516.               (const_int 0)))
  3517.    (set (match_operand:DI 0 "register_operand" "=r")
  3518.     (minus:DI (match_dup 1) (match_dup 2)))]
  3519.   "TARGET_V9"
  3520.   "subcc %1,%2,%0")
  3521.  
  3522. ;; This is anachronistic, and should not be used in v9 software.
  3523. ;; The v9 compiler will widen the args and use muldi3.
  3524.  
  3525. (define_insn "mulsi3"
  3526.   [(set (match_operand:SI 0 "register_operand" "=r")
  3527.     (mult:SI (match_operand:SI 1 "arith_operand" "%r")
  3528.          (match_operand:SI 2 "arith_operand" "rI")))]
  3529.   "TARGET_V8 || TARGET_SPARCLITE"
  3530.   "smul %1,%2,%0"
  3531.   [(set_attr "type" "imul")])
  3532.  
  3533. (define_insn "muldi3"
  3534.   [(set (match_operand:DI 0 "register_operand" "=r")
  3535.     (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3536.          (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3537.   "TARGET_V9"
  3538.   "mulx %1,%2,%0")
  3539.  
  3540. ;; It is not known whether this will match.
  3541.  
  3542. (define_insn "*cmp_mul_set"
  3543.   [(set (match_operand:SI 0 "register_operand" "=r")
  3544.     (mult:SI (match_operand:SI 1 "arith_operand" "%r")
  3545.          (match_operand:SI 2 "arith_operand" "rI")))
  3546.    (set (reg:CC_NOOV 0)
  3547.     (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
  3548.              (const_int 0)))]
  3549.   "TARGET_V8 || TARGET_SPARCLITE"
  3550.   "smulcc %1,%2,%0"
  3551.   [(set_attr "type" "imul")])
  3552.  
  3553. (define_expand "mulsidi3"
  3554.   [(set (match_operand:DI 0 "register_operand" "")
  3555.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
  3556.          (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
  3557.   "TARGET_V8 || TARGET_SPARCLITE"
  3558.   "
  3559. {
  3560.   if (CONSTANT_P (operands[2]))
  3561.     {
  3562.       emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
  3563.       DONE;
  3564.     }
  3565. }")
  3566.  
  3567. (define_insn "*mulsidi3_sp32"
  3568.   [(set (match_operand:DI 0 "register_operand" "=r")
  3569.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3570.          (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
  3571.   "TARGET_V8 || TARGET_SPARCLITE"
  3572.   "smul %1,%2,%R0\;rd %%y,%0"
  3573.   [(set_attr "length" "2")])
  3574.  
  3575. ;; Extra pattern, because sign_extend of a constant isn't valid.
  3576.  
  3577. (define_insn "const_mulsidi3"
  3578.   [(set (match_operand:DI 0 "register_operand" "=r")
  3579.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3580.          (match_operand:SI 2 "small_int" "I")))]
  3581.   "TARGET_V8 || TARGET_SPARCLITE"
  3582.   "smul %1,%2,%R0\;rd %%y,%0"
  3583.   [(set_attr "length" "2")])
  3584.  
  3585. (define_expand "smulsi3_highpart"
  3586.   [(set (match_operand:SI 0 "register_operand" "")
  3587.     (truncate:SI
  3588.      (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
  3589.                    (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
  3590.               (const_int 32))))]
  3591.   "TARGET_V8 || TARGET_SPARCLITE"
  3592.   "
  3593. {
  3594.   if (CONSTANT_P (operands[2]))
  3595.     {
  3596.       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
  3597.       DONE;
  3598.     }
  3599. }")
  3600.  
  3601. (define_insn "*smulsidi3_highpart_sp32"
  3602.   [(set (match_operand:SI 0 "register_operand" "=r")
  3603.     (truncate:SI
  3604.      (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3605.                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
  3606.               (const_int 32))))]
  3607.   "TARGET_V8 || TARGET_SPARCLITE"
  3608.   "smul %1,%2,%%g0\;rd %%y,%0"
  3609.   [(set_attr "length" "2")])
  3610.  
  3611. (define_insn "const_smulsi3_highpart"
  3612.   [(set (match_operand:SI 0 "register_operand" "=r")
  3613.     (truncate:SI
  3614.      (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3615.                    (match_operand:SI 2 "register_operand" "r"))
  3616.               (const_int 32))))]
  3617.   "TARGET_V8 || TARGET_SPARCLITE"
  3618.   "smul %1,%2,%%g0\;rd %%y,%0"
  3619.   [(set_attr "length" "2")])
  3620.  
  3621. (define_expand "umulsidi3"
  3622.   [(set (match_operand:DI 0 "register_operand" "")
  3623.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
  3624.          (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
  3625.   "TARGET_V8 || TARGET_SPARCLITE"
  3626.   "
  3627. {
  3628.   if (CONSTANT_P (operands[2]))
  3629.     {
  3630.       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
  3631.       DONE;
  3632.     }
  3633. }")
  3634.  
  3635. (define_insn "*umulsidi3_sp32"
  3636.   [(set (match_operand:DI 0 "register_operand" "=r")
  3637.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3638.          (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
  3639.   "TARGET_V8 || TARGET_SPARCLITE"
  3640.   "umul %1,%2,%R0\;rd %%y,%0"
  3641.   [(set_attr "length" "2")])
  3642.  
  3643. ;; Extra pattern, because sign_extend of a constant isn't valid.
  3644.  
  3645. (define_insn "const_umulsidi3"
  3646.   [(set (match_operand:DI 0 "register_operand" "=r")
  3647.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3648.          (match_operand:SI 2 "uns_small_int" "")))]
  3649.   "TARGET_V8 || TARGET_SPARCLITE"
  3650.   "umul %1,%2,%R0\;rd %%y,%0"
  3651.   [(set_attr "length" "2")])
  3652.  
  3653. (define_expand "umulsi3_highpart"
  3654.   [(set (match_operand:SI 0 "register_operand" "")
  3655.     (truncate:SI
  3656.      (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
  3657.                    (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
  3658.               (const_int 32))))]
  3659.   "TARGET_V8 || TARGET_SPARCLITE"
  3660.   "
  3661. {
  3662.   if (CONSTANT_P (operands[2]))
  3663.     {
  3664.       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
  3665.       DONE;
  3666.     }
  3667. }")
  3668.  
  3669. (define_insn "*umulsidi3_highpart_sp32"
  3670.   [(set (match_operand:SI 0 "register_operand" "=r")
  3671.     (truncate:SI
  3672.      (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3673.                    (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
  3674.               (const_int 32))))]
  3675.   "TARGET_V8 || TARGET_SPARCLITE"
  3676.   "umul %1,%2,%%g0\;rd %%y,%0"
  3677.   [(set_attr "length" "2")])
  3678.  
  3679. (define_insn "const_umulsi3_highpart"
  3680.   [(set (match_operand:SI 0 "register_operand" "=r")
  3681.     (truncate:SI
  3682.      (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  3683.                    (match_operand:SI 2 "uns_small_int" ""))
  3684.               (const_int 32))))]
  3685.   "TARGET_V8 || TARGET_SPARCLITE"
  3686.   "umul %1,%2,%%g0\;rd %%y,%0"
  3687.   [(set_attr "length" "2")])
  3688.  
  3689. ;; The architecture specifies that there must be 3 instructions between
  3690. ;; a y register write and a use of it for correct results.
  3691.  
  3692. (define_insn "divsi3"
  3693.   [(set (match_operand:SI 0 "register_operand" "=r")
  3694.     (div:SI (match_operand:SI 1 "register_operand" "r")
  3695.         (match_operand:SI 2 "arith_operand" "rI")))
  3696.    (clobber (match_scratch:SI 3 "=&r"))]
  3697.   "TARGET_V8"
  3698.   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
  3699.   [(set_attr "length" "6")])
  3700.  
  3701. (define_insn "divdi3"
  3702.   [(set (match_operand:DI 0 "register_operand" "=r")
  3703.     (div:DI (match_operand:DI 1 "register_operand" "r")
  3704.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3705.   "TARGET_V9"
  3706.   "sdivx %1,%2,%0")
  3707.  
  3708. ;; It is not known whether this will match.
  3709.  
  3710. (define_insn "*cmp_sdiv_cc_set"
  3711.   [(set (match_operand:SI 0 "register_operand" "=r")
  3712.     (div:SI (match_operand:SI 1 "register_operand" "r")
  3713.         (match_operand:SI 2 "arith_operand" "rI")))
  3714.    (set (reg:CC 0)
  3715.     (compare:CC (div:SI (match_dup 1) (match_dup 2))
  3716.             (const_int 0)))
  3717.    (clobber (match_scratch:SI 3 "=&r"))]
  3718.   "TARGET_V8"
  3719.   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
  3720.   [(set_attr "length" "6")])
  3721.  
  3722. (define_insn "udivsi3"
  3723.   [(set (match_operand:SI 0 "register_operand" "=r")
  3724.     (udiv:SI (match_operand:SI 1 "register_operand" "r")
  3725.         (match_operand:SI 2 "arith_operand" "rI")))]
  3726.   "TARGET_V8"
  3727.   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
  3728.   [(set_attr "length" "5")])
  3729.  
  3730. (define_insn "udivdi3"
  3731.   [(set (match_operand:DI 0 "register_operand" "=r")
  3732.     (udiv:DI (match_operand:DI 1 "register_operand" "r")
  3733.          (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3734.   "TARGET_V9"
  3735.   "udivx %1,%2,%0")
  3736.  
  3737. ;; It is not known whether this will match.
  3738.  
  3739. (define_insn "*cmp_udiv_cc_set"
  3740.   [(set (match_operand:SI 0 "register_operand" "=r")
  3741.     (udiv:SI (match_operand:SI 1 "register_operand" "r")
  3742.         (match_operand:SI 2 "arith_operand" "rI")))
  3743.    (set (reg:CC 0)
  3744.     (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
  3745.             (const_int 0)))]
  3746.   "TARGET_V8"
  3747.   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
  3748.   [(set_attr "length" "5")])
  3749.  
  3750. ;;- Boolean instructions
  3751. ;; We define DImode `and` so with DImode `not` we can get
  3752. ;; DImode `andn`.  Other combinations are possible.
  3753.  
  3754. (define_expand "anddi3"
  3755.   [(set (match_operand:DI 0 "register_operand" "")
  3756.     (and:DI (match_operand:DI 1 "arith_double_operand" "")
  3757.         (match_operand:DI 2 "arith_double_operand" "")))]
  3758.   ""
  3759.   "")
  3760.  
  3761. (define_insn "*anddi3_sp32"
  3762.   [(set (match_operand:DI 0 "register_operand" "=r")
  3763.     (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3764.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3765.   "! TARGET_V9"
  3766.   "*
  3767. {
  3768.   rtx op2 = operands[2];
  3769.  
  3770.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  3771.      Give the assembler a chance to pick the move instruction. */
  3772.   if (GET_CODE (op2) == CONST_INT)
  3773.     {
  3774.       int sign = INTVAL (op2);
  3775.       if (sign < 0)
  3776.     return \"mov %1,%0\;and %R1,%2,%R0\";
  3777.       return \"mov 0,%0\;and %R1,%2,%R0\";
  3778.     }
  3779.   else if (GET_CODE (op2) == CONST_DOUBLE)
  3780.     {
  3781.       rtx xoperands[4];
  3782.       xoperands[0] = operands[0];
  3783.       xoperands[1] = operands[1];
  3784.       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
  3785.       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
  3786.       /* We could optimize then operands[1] == operands[0]
  3787.      and either half of the constant is -1.  */
  3788.       output_asm_insn (\"and %R1,%2,%R0\;and %1,%3,%0\", xoperands);
  3789.       return \"\";
  3790.     }
  3791.   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
  3792. }"
  3793.   [(set_attr "length" "2")])
  3794.  
  3795. (define_insn "*anddi3_sp64"
  3796.   [(set (match_operand:DI 0 "register_operand" "=r")
  3797.     (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3798.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3799.   "TARGET_V9"
  3800.   "and %1,%2,%0")
  3801.  
  3802. (define_insn "andsi3"
  3803.   [(set (match_operand:SI 0 "register_operand" "=r")
  3804.     (and:SI (match_operand:SI 1 "arith_operand" "%r")
  3805.         (match_operand:SI 2 "arith_operand" "rI")))]
  3806.   ""
  3807.   "and %1,%2,%0"
  3808.   [(set_attr "type" "ialu")])
  3809.  
  3810. (define_split
  3811.   [(set (match_operand:SI 0 "register_operand" "")
  3812.     (and:SI (match_operand:SI 1 "register_operand" "")
  3813.         (match_operand:SI 2 "" "")))
  3814.    (clobber (match_operand:SI 3 "register_operand" ""))]
  3815.   "GET_CODE (operands[2]) == CONST_INT
  3816.    && !SMALL_INT (operands[2])
  3817.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  3818.   [(set (match_dup 3) (match_dup 4))
  3819.    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
  3820.   "
  3821. {
  3822.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  3823. }")
  3824.  
  3825. (define_insn "*and_not_di_sp32"
  3826.   [(set (match_operand:DI 0 "register_operand" "=r")
  3827.     (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  3828.         (match_operand:DI 2 "register_operand" "r")))]
  3829.   "! TARGET_V9"
  3830.   "andn %2,%1,%0\;andn %R2,%R1,%R0"
  3831.   [(set_attr "length" "2")])
  3832.  
  3833. (define_insn "*and_not_di_sp64"
  3834.   [(set (match_operand:DI 0 "register_operand" "=r")
  3835.     (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  3836.         (match_operand:DI 2 "register_operand" "r")))]
  3837.   "TARGET_V9"
  3838.   "andn %2,%1,%0")
  3839.  
  3840. (define_insn "*and_not_si"
  3841.   [(set (match_operand:SI 0 "register_operand" "=r")
  3842.     (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  3843.         (match_operand:SI 2 "register_operand" "r")))]
  3844.   ""
  3845.   "andn %2,%1,%0"
  3846.   [(set_attr "type" "ialu")])
  3847.  
  3848. (define_expand "iordi3"
  3849.   [(set (match_operand:DI 0 "register_operand" "")
  3850.     (ior:DI (match_operand:DI 1 "arith_double_operand" "")
  3851.         (match_operand:DI 2 "arith_double_operand" "")))]
  3852.   ""
  3853.   "")
  3854.  
  3855. (define_insn "*iordi3_sp32"
  3856.   [(set (match_operand:DI 0 "register_operand" "=r")
  3857.     (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3858.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3859.   "! TARGET_V9"
  3860.   "*
  3861. {
  3862.   rtx op2 = operands[2];
  3863.  
  3864.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  3865.      Give the assembler a chance to pick the move instruction. */
  3866.   if (GET_CODE (op2) == CONST_INT)
  3867.     {
  3868.       int sign = INTVAL (op2);
  3869.       if (sign < 0)
  3870.     return \"mov -1,%0\;or %R1,%2,%R0\";
  3871.       return \"mov %1,%0\;or %R1,%2,%R0\";
  3872.     }
  3873.   else if (GET_CODE (op2) == CONST_DOUBLE)
  3874.     {
  3875.       rtx xoperands[4];
  3876.       xoperands[0] = operands[0];
  3877.       xoperands[1] = operands[1];
  3878.       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
  3879.       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
  3880.       /* We could optimize then operands[1] == operands[0]
  3881.      and either half of the constant is 0.  */
  3882.       output_asm_insn (\"or %R1,%2,%R0\;or %1,%3,%0\", xoperands);
  3883.       return \"\";
  3884.     }
  3885.   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
  3886. }"
  3887.   [(set_attr "length" "2")])
  3888.  
  3889. (define_insn "*iordi3_sp64"
  3890.   [(set (match_operand:DI 0 "register_operand" "=r")
  3891.     (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3892.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3893.   "TARGET_V9"
  3894.   "or %1,%2,%0")
  3895.  
  3896. (define_insn "iorsi3"
  3897.   [(set (match_operand:SI 0 "register_operand" "=r")
  3898.     (ior:SI (match_operand:SI 1 "arith_operand" "%r")
  3899.         (match_operand:SI 2 "arith_operand" "rI")))]
  3900.   ""
  3901.   "or %1,%2,%0"
  3902.   [(set_attr "type" "ialu")])
  3903.  
  3904. (define_split
  3905.   [(set (match_operand:SI 0 "register_operand" "")
  3906.     (ior:SI (match_operand:SI 1 "register_operand" "")
  3907.         (match_operand:SI 2 "" "")))
  3908.    (clobber (match_operand:SI 3 "register_operand" ""))]
  3909.   "GET_CODE (operands[2]) == CONST_INT
  3910.    && !SMALL_INT (operands[2])
  3911.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  3912.   [(set (match_dup 3) (match_dup 4))
  3913.    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
  3914.   "
  3915. {
  3916.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  3917. }")
  3918.  
  3919. (define_insn "*or_not_di_sp32"
  3920.   [(set (match_operand:DI 0 "register_operand" "=r")
  3921.     (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  3922.         (match_operand:DI 2 "register_operand" "r")))]
  3923.   "! TARGET_V9"
  3924.   "orn %2,%1,%0\;orn %R2,%R1,%R0"
  3925.   [(set_attr "length" "2")])
  3926.  
  3927. (define_insn "*or_not_di_sp64"
  3928.   [(set (match_operand:DI 0 "register_operand" "=r")
  3929.     (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  3930.         (match_operand:DI 2 "register_operand" "r")))]
  3931.   "TARGET_V9"
  3932.   "orn %2,%1,%0")
  3933.  
  3934. (define_insn "*or_not_si"
  3935.   [(set (match_operand:SI 0 "register_operand" "=r")
  3936.     (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  3937.         (match_operand:SI 2 "register_operand" "r")))]
  3938.   ""
  3939.   "orn %2,%1,%0"
  3940.   [(set_attr "type" "ialu")])
  3941.  
  3942. (define_expand "xordi3"
  3943.   [(set (match_operand:DI 0 "register_operand" "")
  3944.     (xor:DI (match_operand:DI 1 "arith_double_operand" "")
  3945.         (match_operand:DI 2 "arith_double_operand" "")))]
  3946.   ""
  3947.   "")
  3948.  
  3949. (define_insn "*xorsi3_sp32"
  3950.   [(set (match_operand:DI 0 "register_operand" "=r")
  3951.     (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
  3952.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3953.   "! TARGET_V9"
  3954.   "*
  3955. {
  3956.   rtx op2 = operands[2];
  3957.  
  3958.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  3959.      Give the assembler a chance to pick the move instruction. */
  3960.   if (GET_CODE (op2) == CONST_INT)
  3961.     {
  3962.       int sign = INTVAL (op2);
  3963.       if (sign < 0)
  3964.     return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
  3965.       return \"mov %1,%0\;xor %R1,%2,%R0\";
  3966.     }
  3967.   else if (GET_CODE (op2) == CONST_DOUBLE)
  3968.     {
  3969.       rtx xoperands[4];
  3970.       xoperands[0] = operands[0];
  3971.       xoperands[1] = operands[1];
  3972.       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
  3973.       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
  3974.       /* We could optimize then operands[1] == operands[0]
  3975.      and either half of the constant is 0.  */
  3976.       output_asm_insn (\"xor %R1,%2,%R0\;xor %1,%3,%0\", xoperands);
  3977.       return \"\";
  3978.     }
  3979.   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
  3980. }"
  3981.   [(set_attr "length" "2")])
  3982.  
  3983. (define_insn "*xordi3_sp64"
  3984.   [(set (match_operand:DI 0 "register_operand" "=r")
  3985.     (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
  3986.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  3987.   "TARGET_V9"
  3988.   "xor %r1,%2,%0")
  3989.  
  3990. (define_insn "xorsi3"
  3991.   [(set (match_operand:SI 0 "register_operand" "=r")
  3992.     (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
  3993.         (match_operand:SI 2 "arith_operand" "rI")))]
  3994.   ""
  3995.   "xor %r1,%2,%0"
  3996.   [(set_attr "type" "ialu")])
  3997.  
  3998. (define_split
  3999.   [(set (match_operand:SI 0 "register_operand" "")
  4000.     (xor:SI (match_operand:SI 1 "register_operand" "")
  4001.         (match_operand:SI 2 "" "")))
  4002.    (clobber (match_operand:SI 3 "register_operand" ""))]
  4003.   "GET_CODE (operands[2]) == CONST_INT
  4004.    && !SMALL_INT (operands[2])
  4005.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  4006.   [(set (match_dup 3) (match_dup 4))
  4007.    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
  4008.   "
  4009. {
  4010.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  4011. }")
  4012.  
  4013. (define_split
  4014.   [(set (match_operand:SI 0 "register_operand" "")
  4015.     (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
  4016.             (match_operand:SI 2 "" ""))))
  4017.    (clobber (match_operand:SI 3 "register_operand" ""))]
  4018.   "GET_CODE (operands[2]) == CONST_INT
  4019.    && !SMALL_INT (operands[2])
  4020.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  4021.   [(set (match_dup 3) (match_dup 4))
  4022.    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
  4023.   "
  4024. {
  4025.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  4026. }")
  4027.  
  4028. ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
  4029. ;; Combine now canonicalizes to the rightmost expression.
  4030. (define_insn "*xor_not_di_sp32"
  4031.   [(set (match_operand:DI 0 "register_operand" "=r")
  4032.     (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
  4033.             (match_operand:DI 2 "register_operand" "r"))))]
  4034.   "! TARGET_V9"
  4035.   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
  4036.   [(set_attr "length" "2")])
  4037.  
  4038. (define_insn "*xor_not_di_sp64"
  4039.   [(set (match_operand:DI 0 "register_operand" "=r")
  4040.     (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
  4041.             (match_operand:DI 2 "arith_double_operand" "rHI"))))]
  4042.   "TARGET_V9"
  4043.   "xnor %r1,%2,%0")
  4044.  
  4045. (define_insn "*xor_not_si"
  4046.   [(set (match_operand:SI 0 "register_operand" "=r")
  4047.     (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
  4048.             (match_operand:SI 2 "arith_operand" "rI"))))]
  4049.   ""
  4050.   "xnor %r1,%2,%0"
  4051.   [(set_attr "type" "ialu")])
  4052.  
  4053. ;; These correspond to the above in the case where we also (or only)
  4054. ;; want to set the condition code.  
  4055.  
  4056. (define_insn "*cmp_cc_arith_op"
  4057.   [(set (reg:CC 0)
  4058.     (compare:CC
  4059.      (match_operator:SI 2 "cc_arithop"
  4060.                 [(match_operand:SI 0 "arith_operand" "%r")
  4061.                  (match_operand:SI 1 "arith_operand" "rI")])
  4062.      (const_int 0)))]
  4063.   ""
  4064.   "%A2cc %0,%1,%%g0"
  4065.   [(set_attr "type" "compare")])
  4066.  
  4067. (define_insn "*cmp_ccx_arith_op"
  4068.   [(set (reg:CCX 0)
  4069.     (compare:CCX
  4070.      (match_operator:DI 2 "cc_arithop"
  4071.                 [(match_operand:DI 0 "arith_double_operand" "%r")
  4072.                  (match_operand:DI 1 "arith_double_operand" "rHI")])
  4073.      (const_int 0)))]
  4074.   "TARGET_V9"
  4075.   "%A2cc %0,%1,%%g0"
  4076.   [(set_attr "type" "compare")])
  4077.  
  4078. (define_insn "*cmp_cc_arith_op_set"
  4079.   [(set (reg:CC 0)
  4080.     (compare:CC
  4081.      (match_operator:SI 3 "cc_arithop"
  4082.                 [(match_operand:SI 1 "arith_operand" "%r")
  4083.                  (match_operand:SI 2 "arith_operand" "rI")])
  4084.      (const_int 0)))
  4085.    (set (match_operand:SI 0 "register_operand" "=r")
  4086.     (match_dup 3))]
  4087.   ""
  4088.   "%A3cc %1,%2,%0")
  4089.  
  4090. (define_insn "*cmp_ccx_arith_op_set"
  4091.   [(set (reg:CCX 0)
  4092.     (compare:CCX
  4093.      (match_operator:DI 3 "cc_arithop"
  4094.                 [(match_operand:DI 1 "arith_double_operand" "%r")
  4095.                  (match_operand:DI 2 "arith_double_operand" "rHI")])
  4096.      (const_int 0)))
  4097.    (set (match_operand:DI 0 "register_operand" "=r")
  4098.     (match_dup 3))]
  4099.   "TARGET_V9"
  4100.   "%A3cc %1,%2,%0")
  4101.  
  4102. (define_insn "*cmp_cc_xor_not"
  4103.   [(set (reg:CC 0)
  4104.     (compare:CC
  4105.      (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
  4106.              (match_operand:SI 1 "arith_operand" "rI")))
  4107.      (const_int 0)))]
  4108.   ""
  4109.   "xnorcc %r0,%1,%%g0"
  4110.   [(set_attr "type" "compare")])
  4111.  
  4112. (define_insn "*cmp_ccx_xor_not"
  4113.   [(set (reg:CCX 0)
  4114.     (compare:CCX
  4115.      (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
  4116.              (match_operand:DI 1 "arith_double_operand" "rHI")))
  4117.      (const_int 0)))]
  4118.   "TARGET_V9"
  4119.   "xnorcc %r0,%1,%%g0"
  4120.   [(set_attr "type" "compare")])
  4121.  
  4122. (define_insn "*cmp_cc_xor_not_set"
  4123.   [(set (reg:CC 0)
  4124.     (compare:CC
  4125.      (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
  4126.              (match_operand:SI 2 "arith_operand" "rI")))
  4127.      (const_int 0)))
  4128.    (set (match_operand:SI 0 "register_operand" "=r")
  4129.     (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
  4130.   ""
  4131.   "xnorcc %r1,%2,%0")
  4132.  
  4133. (define_insn "*cmp_ccx_xor_not_set"
  4134.   [(set (reg:CCX 0)
  4135.     (compare:CCX
  4136.      (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
  4137.              (match_operand:DI 2 "arith_double_operand" "rHI")))
  4138.      (const_int 0)))
  4139.    (set (match_operand:DI 0 "register_operand" "=r")
  4140.     (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
  4141.   "TARGET_V9"
  4142.   "xnorcc %r1,%2,%0")
  4143.  
  4144. (define_insn "*cmp_cc_arith_op_not"
  4145.   [(set (reg:CC 0)
  4146.     (compare:CC
  4147.      (match_operator:SI 2 "cc_arithopn"
  4148.                 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
  4149.                  (match_operand:SI 1 "reg_or_0_operand" "rJ")])
  4150.      (const_int 0)))]
  4151.   ""
  4152.   "%B2cc %r1,%0,%%g0"
  4153.   [(set_attr "type" "compare")])
  4154.  
  4155. (define_insn "*cmp_ccx_arith_op_not"
  4156.   [(set (reg:CCX 0)
  4157.     (compare:CCX
  4158.      (match_operator:DI 2 "cc_arithopn"
  4159.                 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
  4160.                  (match_operand:DI 1 "reg_or_0_operand" "rJ")])
  4161.      (const_int 0)))]
  4162.   "TARGET_V9"
  4163.   "%B2cc %r1,%0,%%g0"
  4164.   [(set_attr "type" "compare")])
  4165.  
  4166. (define_insn "*cmp_cc_arith_op_not_set"
  4167.   [(set (reg:CC 0)
  4168.     (compare:CC
  4169.      (match_operator:SI 3 "cc_arithopn"
  4170.                 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
  4171.                  (match_operand:SI 2 "reg_or_0_operand" "rJ")])
  4172.      (const_int 0)))
  4173.    (set (match_operand:SI 0 "register_operand" "=r")
  4174.     (match_dup 3))]
  4175.   ""
  4176.   "%B3cc %r2,%1,%0")
  4177.  
  4178. (define_insn "*cmp_ccx_arith_op_not_set"
  4179.   [(set (reg:CCX 0)
  4180.     (compare:CCX
  4181.      (match_operator:DI 3 "cc_arithopn"
  4182.                 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
  4183.                  (match_operand:DI 2 "reg_or_0_operand" "rJ")])
  4184.      (const_int 0)))
  4185.    (set (match_operand:DI 0 "register_operand" "=r")
  4186.     (match_dup 3))]
  4187.   "TARGET_V9"
  4188.   "%B3cc %r2,%1,%0")
  4189.  
  4190. ;; We cannot use the "neg" pseudo insn because the Sun assembler
  4191. ;; does not know how to make it work for constants.
  4192.  
  4193. (define_expand "negdi2"
  4194.   [(set (match_operand:DI 0 "register_operand" "=r")
  4195.     (neg:DI (match_operand:DI 1 "register_operand" "r")))]
  4196.   ""
  4197.   "
  4198. {
  4199.   if (! TARGET_V9)
  4200.     {
  4201.       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  4202.               gen_rtx (SET, VOIDmode, operand0,
  4203.                    gen_rtx (NEG, DImode, operand1)),
  4204.               gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
  4205.       DONE;
  4206.     }
  4207. }")
  4208.  
  4209. (define_insn "*negdi2_sp32"
  4210.   [(set (match_operand:DI 0 "register_operand" "=r")
  4211.     (neg:DI (match_operand:DI 1 "register_operand" "r")))
  4212.    (clobber (reg:SI 0))]
  4213.   "! TARGET_V9"
  4214.   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
  4215.   [(set_attr "type" "unary")
  4216.    (set_attr "length" "2")])
  4217.  
  4218. (define_insn "*negdi2_sp64"
  4219.   [(set (match_operand:DI 0 "register_operand" "=r")
  4220.     (neg:DI (match_operand:DI 1 "register_operand" "r")))]
  4221.   "TARGET_V9"
  4222.   "sub %%g0,%1,%0"
  4223.   [(set_attr "type" "unary")
  4224.    (set_attr "length" "1")])
  4225.  
  4226. (define_insn "negsi2"
  4227.   [(set (match_operand:SI 0 "register_operand" "=r")
  4228.     (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  4229.   ""
  4230.   "sub %%g0,%1,%0"
  4231.   [(set_attr "type" "unary")])
  4232.  
  4233. (define_insn "*cmp_cc_neg"
  4234.   [(set (reg:CC_NOOV 0)
  4235.     (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
  4236.              (const_int 0)))]
  4237.   ""
  4238.   "subcc %%g0,%0,%%g0"
  4239.   [(set_attr "type" "compare")])
  4240.  
  4241. (define_insn "*cmp_ccx_neg"
  4242.   [(set (reg:CCX_NOOV 0)
  4243.     (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
  4244.               (const_int 0)))]
  4245.   "TARGET_V9"
  4246.   "subcc %%g0,%0,%%g0"
  4247.   [(set_attr "type" "compare")])
  4248.  
  4249. (define_insn "*cmp_cc_set_neg"
  4250.   [(set (reg:CC_NOOV 0)
  4251.     (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
  4252.              (const_int 0)))
  4253.    (set (match_operand:SI 0 "register_operand" "=r")
  4254.     (neg:SI (match_dup 1)))]
  4255.   ""
  4256.   "subcc %%g0,%1,%0"
  4257.   [(set_attr "type" "unary")])
  4258.  
  4259. (define_insn "*cmp_ccx_set_neg"
  4260.   [(set (reg:CCX_NOOV 0)
  4261.     (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
  4262.               (const_int 0)))
  4263.    (set (match_operand:DI 0 "register_operand" "=r")
  4264.     (neg:DI (match_dup 1)))]
  4265.   "TARGET_V9"
  4266.   "subcc %%g0,%1,%0"
  4267.   [(set_attr "type" "unary")])
  4268.  
  4269. ;; We cannot use the "not" pseudo insn because the Sun assembler
  4270. ;; does not know how to make it work for constants.
  4271. (define_expand "one_cmpldi2"
  4272.   [(set (match_operand:DI 0 "register_operand" "")
  4273.     (not:DI (match_operand:DI 1 "register_operand" "")))]
  4274.   ""
  4275.   "")
  4276.  
  4277. (define_insn "*one_cmpldi2_sp32"
  4278.   [(set (match_operand:DI 0 "register_operand" "=r")
  4279.     (not:DI (match_operand:DI 1 "register_operand" "r")))]
  4280.   "! TARGET_V9"
  4281.   "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
  4282.   [(set_attr "type" "unary")
  4283.    (set_attr "length" "2")])
  4284.  
  4285. (define_insn "*one_cmpldi2_sp64"
  4286.   [(set (match_operand:DI 0 "register_operand" "=r")
  4287.     (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
  4288.   "TARGET_V9"
  4289.   "xnor %%g0,%1,%0"
  4290.   [(set_attr "type" "unary")])
  4291.  
  4292. (define_insn "one_cmplsi2"
  4293.   [(set (match_operand:SI 0 "register_operand" "=r")
  4294.     (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
  4295.   ""
  4296.   "xnor %%g0,%1,%0"
  4297.   [(set_attr "type" "unary")])
  4298.  
  4299. (define_insn "*cmp_cc_not"
  4300.   [(set (reg:CC 0)
  4301.     (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
  4302.             (const_int 0)))]
  4303.   ""
  4304.   "xnorcc %%g0,%0,%%g0"
  4305.   [(set_attr "type" "compare")])
  4306.  
  4307. (define_insn "*cmp_ccx_not"
  4308.   [(set (reg:CCX 0)
  4309.     (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
  4310.              (const_int 0)))]
  4311.   "TARGET_V9"
  4312.   "xnorcc %%g0,%0,%%g0"
  4313.   [(set_attr "type" "compare")])
  4314.  
  4315. (define_insn "*cmp_cc_set_not"
  4316.   [(set (reg:CC 0)
  4317.     (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
  4318.             (const_int 0)))
  4319.    (set (match_operand:SI 0 "register_operand" "=r")
  4320.     (not:SI (match_dup 1)))]
  4321.   ""
  4322.   "xnorcc %%g0,%1,%0"
  4323.   [(set_attr "type" "unary")])
  4324.  
  4325. (define_insn "*cmp_ccx_set_not"
  4326.   [(set (reg:CCX 0)
  4327.     (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
  4328.             (const_int 0)))
  4329.    (set (match_operand:DI 0 "register_operand" "=r")
  4330.     (not:DI (match_dup 1)))]
  4331.   "TARGET_V9"
  4332.   "xnorcc %%g0,%1,%0"
  4333.   [(set_attr "type" "unary")])
  4334.  
  4335. ;; Floating point arithmetic instructions.
  4336.  
  4337. (define_insn "addtf3"
  4338.   [(set (match_operand:TF 0 "register_operand" "=e")
  4339.     (plus:TF (match_operand:TF 1 "register_operand" "e")
  4340.          (match_operand:TF 2 "register_operand" "e")))]
  4341.   "TARGET_FPU && TARGET_HARD_QUAD"
  4342.   "faddq %1,%2,%0"
  4343.   [(set_attr "type" "fp")])
  4344.  
  4345. (define_insn "adddf3"
  4346.   [(set (match_operand:DF 0 "register_operand" "=e")
  4347.     (plus:DF (match_operand:DF 1 "register_operand" "e")
  4348.          (match_operand:DF 2 "register_operand" "e")))]
  4349.   "TARGET_FPU"
  4350.   "faddd %1,%2,%0"
  4351.   [(set_attr "type" "fp")])
  4352.  
  4353. (define_insn "addsf3"
  4354.   [(set (match_operand:SF 0 "register_operand" "=f")
  4355.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  4356.          (match_operand:SF 2 "register_operand" "f")))]
  4357.   "TARGET_FPU"
  4358.   "fadds %1,%2,%0"
  4359.   [(set_attr "type" "fp")])
  4360.  
  4361. (define_insn "subtf3"
  4362.   [(set (match_operand:TF 0 "register_operand" "=e")
  4363.     (minus:TF (match_operand:TF 1 "register_operand" "e")
  4364.           (match_operand:TF 2 "register_operand" "e")))]
  4365.   "TARGET_FPU && TARGET_HARD_QUAD"
  4366.   "fsubq %1,%2,%0"
  4367.   [(set_attr "type" "fp")])
  4368.  
  4369. (define_insn "subdf3"
  4370.   [(set (match_operand:DF 0 "register_operand" "=e")
  4371.     (minus:DF (match_operand:DF 1 "register_operand" "e")
  4372.           (match_operand:DF 2 "register_operand" "e")))]
  4373.   "TARGET_FPU"
  4374.   "fsubd %1,%2,%0"
  4375.   [(set_attr "type" "fp")])
  4376.  
  4377. (define_insn "subsf3"
  4378.   [(set (match_operand:SF 0 "register_operand" "=f")
  4379.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  4380.           (match_operand:SF 2 "register_operand" "f")))]
  4381.   "TARGET_FPU"
  4382.   "fsubs %1,%2,%0"
  4383.   [(set_attr "type" "fp")])
  4384.  
  4385. (define_insn "multf3"
  4386.   [(set (match_operand:TF 0 "register_operand" "=e")
  4387.     (mult:TF (match_operand:TF 1 "register_operand" "e")
  4388.          (match_operand:TF 2 "register_operand" "e")))]
  4389.   "TARGET_FPU && TARGET_HARD_QUAD"
  4390.   "fmulq %1,%2,%0"
  4391.   [(set_attr "type" "fpmul")])
  4392.  
  4393. (define_insn "muldf3"
  4394.   [(set (match_operand:DF 0 "register_operand" "=e")
  4395.     (mult:DF (match_operand:DF 1 "register_operand" "e")
  4396.          (match_operand:DF 2 "register_operand" "e")))]
  4397.   "TARGET_FPU"
  4398.   "fmuld %1,%2,%0"
  4399.   [(set_attr "type" "fpmul")])
  4400.  
  4401. (define_insn "mulsf3"
  4402.   [(set (match_operand:SF 0 "register_operand" "=f")
  4403.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  4404.          (match_operand:SF 2 "register_operand" "f")))]
  4405.   "TARGET_FPU"
  4406.   "fmuls %1,%2,%0"
  4407.   [(set_attr "type" "fpmul")])
  4408.  
  4409. (define_insn "*muldf3_extend"
  4410.   [(set (match_operand:DF 0 "register_operand" "=e")
  4411.     (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
  4412.          (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
  4413.   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
  4414.   "fsmuld %1,%2,%0"
  4415.   [(set_attr "type" "fpmul")])
  4416.  
  4417. (define_insn "*multf3_extend"
  4418.   [(set (match_operand:TF 0 "register_operand" "=e")
  4419.     (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
  4420.          (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
  4421.   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
  4422.   "fdmulq %1,%2,%0"
  4423.   [(set_attr "type" "fpmul")])
  4424.  
  4425. ;; don't have timing for quad-prec. divide.
  4426. (define_insn "divtf3"
  4427.   [(set (match_operand:TF 0 "register_operand" "=e")
  4428.     (div:TF (match_operand:TF 1 "register_operand" "e")
  4429.         (match_operand:TF 2 "register_operand" "e")))]
  4430.   "TARGET_FPU && TARGET_HARD_QUAD"
  4431.   "fdivq %1,%2,%0"
  4432.   [(set_attr "type" "fpdivd")])
  4433.  
  4434. (define_insn "divdf3"
  4435.   [(set (match_operand:DF 0 "register_operand" "=e")
  4436.     (div:DF (match_operand:DF 1 "register_operand" "e")
  4437.         (match_operand:DF 2 "register_operand" "e")))]
  4438.   "TARGET_FPU"
  4439.   "fdivd %1,%2,%0"
  4440.   [(set_attr "type" "fpdivd")])
  4441.  
  4442. (define_insn "divsf3"
  4443.   [(set (match_operand:SF 0 "register_operand" "=f")
  4444.     (div:SF (match_operand:SF 1 "register_operand" "f")
  4445.         (match_operand:SF 2 "register_operand" "f")))]
  4446.   "TARGET_FPU"
  4447.   "fdivs %1,%2,%0"
  4448.   [(set_attr "type" "fpdivs")])
  4449.  
  4450. (define_insn "negtf2"
  4451.   [(set (match_operand:TF 0 "register_operand" "=e,e")
  4452.     (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
  4453.   "TARGET_FPU"
  4454.   "*
  4455. {
  4456.   if (TARGET_V9)
  4457.     return \"fnegd %1,%0\"; /* Can't use fnegs, won't work with upper regs.  */
  4458.   else if (which_alternative == 0)
  4459.    return \"fnegs %0,%0\";
  4460.   else
  4461.    return \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
  4462. }"
  4463.   [(set_attr "type" "fp")
  4464.    (set_attr_alternative "length"
  4465.      [(const_int 1)
  4466.       (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
  4467.  
  4468. (define_insn "negdf2"
  4469.   [(set (match_operand:DF 0 "register_operand" "=e,e")
  4470.     (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
  4471.   "TARGET_FPU"
  4472.   "*
  4473. {
  4474.   if (TARGET_V9)
  4475.     return \"fnegd %1,%0\";
  4476.   else if (which_alternative == 0)
  4477.    return \"fnegs %0,%0\";
  4478.   else
  4479.    return \"fnegs %1,%0\;fmovs %R1,%R0\";
  4480. }"
  4481.   [(set_attr "type" "fp")
  4482.    (set_attr_alternative "length"
  4483.      [(const_int 1)
  4484.       (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
  4485.  
  4486. (define_insn "negsf2"
  4487.   [(set (match_operand:SF 0 "register_operand" "=f")
  4488.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  4489.   "TARGET_FPU"
  4490.   "fnegs %1,%0"
  4491.   [(set_attr "type" "fp")])
  4492.  
  4493. (define_insn "abstf2"
  4494.   [(set (match_operand:TF 0 "register_operand" "=e,e")
  4495.     (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
  4496.   "TARGET_FPU"
  4497.   "*
  4498. {
  4499.   if (TARGET_V9)
  4500.     return \"fabsd %1,%0\"; /* Can't use fabss, won't work with upper regs.  */
  4501.   else if (which_alternative == 0)
  4502.     return \"fabss %0,%0\";
  4503.   else
  4504.     return \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
  4505. }"
  4506.   [(set_attr "type" "fp")
  4507.    (set_attr_alternative "length"
  4508.      [(const_int 1)
  4509.       (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
  4510.  
  4511. (define_insn "absdf2"
  4512.   [(set (match_operand:DF 0 "register_operand" "=e,e")
  4513.     (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
  4514.   "TARGET_FPU"
  4515.   "*
  4516. {
  4517.   if (TARGET_V9)
  4518.     return \"fabsd %1,%0\";
  4519.   else if (which_alternative == 0)
  4520.     return \"fabss %0,%0\";
  4521.   else
  4522.     return \"fabss %1,%0\;fmovs %R1,%R0\";
  4523. }"
  4524.   [(set_attr "type" "fp")
  4525.    (set_attr_alternative "length"
  4526.      [(const_int 1)
  4527.       (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
  4528.  
  4529. (define_insn "abssf2"
  4530.   [(set (match_operand:SF 0 "register_operand" "=f")
  4531.     (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  4532.   "TARGET_FPU"
  4533.   "fabss %1,%0"
  4534.   [(set_attr "type" "fp")])
  4535.  
  4536. (define_insn "sqrttf2"
  4537.   [(set (match_operand:TF 0 "register_operand" "=e")
  4538.     (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
  4539.   "TARGET_FPU && TARGET_HARD_QUAD"
  4540.   "fsqrtq %1,%0"
  4541.   [(set_attr "type" "fpsqrt")])
  4542.  
  4543. (define_insn "sqrtdf2"
  4544.   [(set (match_operand:DF 0 "register_operand" "=e")
  4545.     (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
  4546.   "TARGET_FPU"
  4547.   "fsqrtd %1,%0"
  4548.   [(set_attr "type" "fpsqrt")])
  4549.  
  4550. (define_insn "sqrtsf2"
  4551.   [(set (match_operand:SF 0 "register_operand" "=f")
  4552.     (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
  4553.   "TARGET_FPU"
  4554.   "fsqrts %1,%0"
  4555.   [(set_attr "type" "fpsqrt")])
  4556.  
  4557. ;;- arithmetic shift instructions
  4558.  
  4559. (define_insn "ashlsi3"
  4560.   [(set (match_operand:SI 0 "register_operand" "=r")
  4561.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  4562.            (match_operand:SI 2 "arith_operand" "rI")))]
  4563.   ""
  4564.   "*
  4565. {
  4566.   if (GET_CODE (operands[2]) == CONST_INT
  4567.       && (unsigned) INTVAL (operands[2]) > 31)
  4568.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
  4569.  
  4570.   return \"sll %1,%2,%0\";
  4571. }"
  4572.   [(set_attr "type" "shift")])
  4573.  
  4574. (define_insn "ashldi3"
  4575.   [(set (match_operand:DI 0 "register_operand" "=r")
  4576.     (ashift:DI (match_operand:DI 1 "register_operand" "r")
  4577.            (match_operand:SI 2 "arith_operand" "rI")))]
  4578.   "TARGET_V9"
  4579.   "*
  4580. {
  4581.   if (GET_CODE (operands[2]) == CONST_INT
  4582.       && (unsigned) INTVAL (operands[2]) > 63)
  4583.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
  4584.  
  4585.   return \"sllx %1,%2,%0\";
  4586. }")
  4587.  
  4588. (define_insn "*cmp_cc_ashift_1"
  4589.   [(set (reg:CC_NOOV 0)
  4590.     (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
  4591.                     (const_int 1))
  4592.              (const_int 0)))]
  4593.   ""
  4594.   "addcc %0,%0,%%g0"
  4595.   [(set_attr "type" "compare")])
  4596.  
  4597. (define_insn "*cmp_cc_set_ashift_1"
  4598.   [(set (reg:CC_NOOV 0)
  4599.     (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
  4600.                     (const_int 1))
  4601.              (const_int 0)))
  4602.    (set (match_operand:SI 0 "register_operand" "=r")
  4603.     (ashift:SI (match_dup 1) (const_int 1)))]
  4604.   ""
  4605.   "addcc %1,%1,%0")
  4606.  
  4607. (define_insn "ashrsi3"
  4608.   [(set (match_operand:SI 0 "register_operand" "=r")
  4609.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  4610.              (match_operand:SI 2 "arith_operand" "rI")))]
  4611.   ""
  4612.   "*
  4613. {
  4614.   if (GET_CODE (operands[2]) == CONST_INT
  4615.       && (unsigned) INTVAL (operands[2]) > 31)
  4616.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
  4617.  
  4618.   return \"sra %1,%2,%0\";
  4619. }"
  4620.   [(set_attr "type" "shift")])
  4621.  
  4622. (define_insn "ashrdi3"
  4623.   [(set (match_operand:DI 0 "register_operand" "=r")
  4624.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
  4625.              (match_operand:SI 2 "arith_operand" "rI")))]
  4626.   "TARGET_V9"
  4627.   "*
  4628. {
  4629.   if (GET_CODE (operands[2]) == CONST_INT
  4630.       && (unsigned) INTVAL (operands[2]) > 63)
  4631.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
  4632.  
  4633.   return \"srax %1,%2,%0\";
  4634. }")
  4635.  
  4636. (define_insn "lshrsi3"
  4637.   [(set (match_operand:SI 0 "register_operand" "=r")
  4638.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  4639.              (match_operand:SI 2 "arith_operand" "rI")))]
  4640.   ""
  4641.   "*
  4642. {
  4643.   if (GET_CODE (operands[2]) == CONST_INT
  4644.       && (unsigned) INTVAL (operands[2]) > 31)
  4645.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
  4646.  
  4647.   return \"srl %1,%2,%0\";
  4648. }"
  4649.   [(set_attr "type" "shift")])
  4650.  
  4651. (define_insn "lshrdi3"
  4652.   [(set (match_operand:DI 0 "register_operand" "=r")
  4653.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
  4654.              (match_operand:SI 2 "arith_operand" "rI")))]
  4655.   "TARGET_V9"
  4656.   "*
  4657. {
  4658.   if (GET_CODE (operands[2]) == CONST_INT
  4659.       && (unsigned) INTVAL (operands[2]) > 63)
  4660.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
  4661.  
  4662.   return \"srlx %1,%2,%0\";
  4663. }")
  4664.  
  4665. ;; Unconditional and other jump instructions
  4666. ;; On the Sparc, by setting the annul bit on an unconditional branch, the
  4667. ;; following insn is never executed.  This saves us a nop.  Dbx does not
  4668. ;; handle such branches though, so we only use them when optimizing.
  4669. (define_insn "jump"
  4670.   [(set (pc) (label_ref (match_operand 0 "" "")))]
  4671.   ""
  4672.   "b%* %l0%("
  4673.   [(set_attr "type" "uncond_branch")])
  4674.  
  4675. (define_expand "tablejump"
  4676.   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
  4677.           (use (label_ref (match_operand 1 "" "")))])]
  4678.   "! TARGET_MEDANY"
  4679.   "
  4680. {
  4681.   if (GET_MODE (operands[0]) != Pmode)
  4682.     abort ();
  4683.  
  4684.   /* We need to use the PC value in %o7 that was set up when the address
  4685.      of the label was loaded into a register, so we need different RTL.  */
  4686.   if (flag_pic)
  4687.     {
  4688.       if (!TARGET_PTR64)
  4689.     emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
  4690.       else
  4691.     emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
  4692.       DONE;
  4693.     }
  4694. }")
  4695.  
  4696. (define_insn "pic_tablejump_32"
  4697.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  4698.    (use (label_ref (match_operand 1 "" "")))
  4699.    (use (reg:SI 15))]
  4700.   "! TARGET_PTR64"
  4701.   "jmp %%o7+%0%#"
  4702.   [(set_attr "type" "uncond_branch")])
  4703.  
  4704. (define_insn "pic_tablejump_64"
  4705.   [(set (pc) (match_operand:DI 0 "register_operand" "r"))
  4706.    (use (label_ref (match_operand 1 "" "")))
  4707.    (use (reg:DI 15))]
  4708.   "TARGET_PTR64"
  4709.   "jmp %%o7+%0%#"
  4710.   [(set_attr "type" "uncond_branch")])
  4711.  
  4712. (define_insn "*tablejump_sp32"
  4713.   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
  4714.    (use (label_ref (match_operand 1 "" "")))]
  4715.   "! TARGET_PTR64"
  4716.   "jmp %a0%#"
  4717.   [(set_attr "type" "uncond_branch")])
  4718.  
  4719. (define_insn "*tablejump_sp64"
  4720.   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
  4721.    (use (label_ref (match_operand 1 "" "")))]
  4722.   "TARGET_PTR64"
  4723.   "jmp %a0%#"
  4724.   [(set_attr "type" "uncond_branch")])
  4725.  
  4726. (define_insn "*get_pc_sp32"
  4727.   [(set (pc) (label_ref (match_operand 0 "" "")))
  4728.    (set (reg:SI 15) (label_ref (match_dup 0)))]
  4729.   "! TARGET_PTR64"
  4730.   "call %l0%#"
  4731.   [(set_attr "type" "uncond_branch")])
  4732.  
  4733. (define_insn "*get_pc_sp64"
  4734.   [(set (pc) (label_ref (match_operand 0 "" "")))
  4735.    (set (reg:DI 15) (label_ref (match_dup 0)))]
  4736.   "TARGET_PTR64"
  4737.   "call %l0%#"
  4738.   [(set_attr "type" "uncond_branch")])
  4739.  
  4740. ;; Implement a switch statement for the medium/anywhere code model.
  4741. ;; This wouldn't be necessary if we could distinguish label refs of the jump
  4742. ;; table from other label refs.  The problem is that jump tables live in the
  4743. ;; .rodata section and thus we need to add %g4 to get their address.
  4744.  
  4745. (define_expand "casesi"
  4746.   [(set (match_dup 5)
  4747.     (minus:SI (match_operand:SI 0 "register_operand" "")
  4748.           (match_operand:SI 1 "nonmemory_operand" "")))
  4749.    (set (reg:CC 0)
  4750.     (compare:CC (match_dup 5)
  4751.             (match_operand:SI 2 "nonmemory_operand" "")))
  4752.    (set (pc)
  4753.     (if_then_else (gtu (reg:CC 0)
  4754.                (const_int 0))
  4755.               (label_ref (match_operand 4 "" ""))
  4756.               (pc)))
  4757.    (parallel [(set (match_dup 6) (high:DI (label_ref (match_operand 3 "" ""))))
  4758.           (clobber (reg:DI 1))])
  4759.    (set (match_dup 6)
  4760.     (lo_sum:DI (match_dup 6) (label_ref (match_dup 3))))
  4761.    (set (match_dup 6) (plus:DI (match_dup 6) (reg:DI 4)))
  4762.    (set (match_dup 7) (zero_extend:DI (match_dup 5)))
  4763.    (set (match_dup 7) (ashift:DI (match_dup 7) (const_int 3)))
  4764.    (set (match_dup 7) (mem:DI (plus:DI (match_dup 6) (match_dup 7))))
  4765.    (set (pc) (match_dup 7))]
  4766.   "TARGET_MEDANY"
  4767.   "
  4768. {
  4769.   operands[5] = gen_reg_rtx (SImode);
  4770.   operands[6] = gen_reg_rtx (DImode);
  4771.   operands[7] = gen_reg_rtx (DImode);
  4772. }")
  4773.  
  4774. ;; This pattern recognizes the "instruction" that appears in 
  4775. ;; a function call that wants a structure value, 
  4776. ;; to inform the called function if compiled with Sun CC.
  4777. ;(define_insn "*unimp_insn"
  4778. ;  [(match_operand:SI 0 "immediate_operand" "")]
  4779. ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
  4780. ;  "unimp %0"
  4781. ;  [(set_attr "type" "marker")])
  4782.  
  4783. ;;- jump to subroutine
  4784. (define_expand "call"
  4785.   ;; Note that this expression is not used for generating RTL.
  4786.   ;; All the RTL is generated explicitly below.
  4787.   [(call (match_operand 0 "call_operand" "")
  4788.      (match_operand 3 "" "i"))]
  4789.   ;; operands[2] is next_arg_register
  4790.   ;; operands[3] is struct_value_size_rtx.
  4791.   ""
  4792.   "
  4793. {
  4794.   rtx fn_rtx, nregs_rtx;
  4795.  
  4796.    if (GET_MODE (operands[0]) != FUNCTION_MODE)
  4797.     abort ();
  4798.  
  4799.  if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
  4800.     {
  4801.       /* This is really a PIC sequence.  We want to represent
  4802.      it as a funny jump so it's delay slots can be filled. 
  4803.  
  4804.      ??? But if this really *is* a CALL, will not it clobber the
  4805.      call-clobbered registers?  We lose this if it is a JUMP_INSN.
  4806.      Why cannot we have delay slots filled if it were a CALL?  */
  4807.  
  4808.       if (! TARGET_V9 && INTVAL (operands[3]) != 0)
  4809.     emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
  4810.                  gen_rtx (SET, VOIDmode, pc_rtx,
  4811.                       XEXP (operands[0], 0)),
  4812.                  operands[3],
  4813.                  gen_rtx (CLOBBER, VOIDmode,
  4814.                       gen_rtx (REG, Pmode, 15)))));
  4815.       else
  4816.     emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  4817.                  gen_rtx (SET, VOIDmode, pc_rtx,
  4818.                       XEXP (operands[0], 0)),
  4819.                  gen_rtx (CLOBBER, VOIDmode,
  4820.                       gen_rtx (REG, Pmode, 15)))));
  4821.       goto finish_call;
  4822.     }
  4823.  
  4824.   fn_rtx = operands[0];
  4825.  
  4826.   /* Count the number of parameter registers being used by this call.
  4827.      if that argument is NULL, it means we are using them all, which
  4828.      means 6 on the sparc.  */
  4829. #if 0
  4830.   if (operands[2])
  4831.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
  4832.   else
  4833.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  4834. #else
  4835.   nregs_rtx = const0_rtx;
  4836. #endif
  4837.  
  4838.   if (! TARGET_V9 && INTVAL (operands[3]) != 0)
  4839.     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
  4840.                  gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  4841.                  operands[3],
  4842.                  gen_rtx (CLOBBER, VOIDmode,
  4843.                            gen_rtx (REG, Pmode, 15)))));
  4844.   else
  4845.     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  4846.                  gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  4847.                  gen_rtx (CLOBBER, VOIDmode,
  4848.                            gen_rtx (REG, Pmode, 15)))));
  4849.  
  4850.  finish_call:
  4851. #if 0
  4852.   /* If this call wants a structure value,
  4853.      emit an unimp insn to let the called function know about this.  */
  4854.   if (! TARGET_V9 && INTVAL (operands[3]) > 0)
  4855.     {
  4856.       rtx insn = emit_insn (operands[3]);
  4857.       SCHED_GROUP_P (insn) = 1;
  4858.     }
  4859. #endif
  4860.  
  4861.   DONE;
  4862. }")
  4863.  
  4864. ;; We can't use the same pattern for these two insns, because then registers
  4865. ;; in the address may not be properly reloaded.
  4866.  
  4867. (define_insn "*call_address_sp32"
  4868.   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
  4869.      (match_operand 1 "" ""))
  4870.    (clobber (reg:SI 15))]
  4871.   ;;- Do not use operand 1 for most machines.
  4872.   "! TARGET_PTR64"
  4873.   "*
  4874. {
  4875.   return \"call %a0,%1%#\";
  4876. }"
  4877.   [(set_attr "type" "call")])
  4878.  
  4879. (define_insn "*call_symbolic_sp32"
  4880.   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
  4881.      (match_operand 1 "" ""))
  4882.    (clobber (reg:SI 15))]
  4883.   ;;- Do not use operand 1 for most machines.
  4884.   "! TARGET_PTR64"
  4885.   "*
  4886. {
  4887.   return \"call %a0,%1%#\";
  4888. }"
  4889.   [(set_attr "type" "call")])
  4890.  
  4891. (define_insn "*call_address_sp64"
  4892.   [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
  4893.      (match_operand 1 "" ""))
  4894.    (clobber (reg:DI 15))]
  4895.   ;;- Do not use operand 1 for most machines.
  4896.   "TARGET_PTR64"
  4897.   "*
  4898. {
  4899.   return \"call %a0,%1%#\";
  4900. }"
  4901.   [(set_attr "type" "call")])
  4902.  
  4903. (define_insn "*call_symbolic_sp64"
  4904.   [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
  4905.      (match_operand 1 "" ""))
  4906.    (clobber (reg:DI 15))]
  4907.   ;;- Do not use operand 1 for most machines.
  4908.   "TARGET_PTR64"
  4909.   "*
  4910. {
  4911.   return \"call %a0,%1%#\";
  4912. }"
  4913.   [(set_attr "type" "call")])
  4914.  
  4915. ;; This is a call that wants a structure value.
  4916. ;; There is no such critter for v9 (??? we may need one anyway).
  4917. (define_insn "*call_address_struct_value_sp32"
  4918.   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
  4919.      (match_operand 1 "" ""))
  4920.    (match_operand 2 "immediate_operand" "")
  4921.    (clobber (reg:SI 15))]
  4922.   ;;- Do not use operand 1 for most machines.
  4923.   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
  4924.   "*
  4925. {
  4926.   return \"call %a0,%1\;nop\;unimp %2\";
  4927. }"
  4928.   [(set_attr "type" "call_no_delay_slot")])
  4929.  
  4930. ;; This is a call that wants a structure value.
  4931. ;; There is no such critter for v9 (??? we may need one anyway).
  4932. (define_insn "*call_symbolic_struct_value_sp32"
  4933.   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
  4934.      (match_operand 1 "" ""))
  4935.    (match_operand 2 "immediate_operand" "")
  4936.    (clobber (reg:SI 15))]
  4937.   ;;- Do not use operand 1 for most machines.
  4938.   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
  4939.   "*
  4940. {
  4941.   return \"call %a0,%1\;nop\;unimp %2\";
  4942. }"
  4943.   [(set_attr "type" "call_no_delay_slot")])
  4944.  
  4945. ;; This is a call that may want a structure value.  This is used for
  4946. ;; untyped_calls.
  4947. (define_insn "*call_address_untyped_struct_value_sp32"
  4948.   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
  4949.      (match_operand 1 "" ""))
  4950.    (match_operand 2 "immediate_operand" "")
  4951.    (clobber (reg:SI 15))]
  4952.   ;;- Do not use operand 1 for most machines.
  4953.   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
  4954.   "*
  4955. {
  4956.   return \"call %a0,%1\;nop\;nop\";
  4957. }"
  4958.   [(set_attr "type" "call_no_delay_slot")])
  4959.  
  4960. ;; This is a call that wants a structure value.
  4961. (define_insn "*call_symbolic_untyped_struct_value_sp32"
  4962.   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
  4963.      (match_operand 1 "" ""))
  4964.    (match_operand 2 "immediate_operand" "")
  4965.    (clobber (reg:SI 15))]
  4966.   ;;- Do not use operand 1 for most machines.
  4967.   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
  4968.   "*
  4969. {
  4970.   return \"call %a0,%1\;nop\;nop\";
  4971. }"
  4972.   [(set_attr "type" "call_no_delay_slot")])
  4973.  
  4974. (define_expand "call_value"
  4975.   ;; Note that this expression is not used for generating RTL.
  4976.   ;; All the RTL is generated explicitly below.
  4977.   [(set (match_operand 0 "register_operand" "=rf")
  4978.     (call (match_operand:SI 1 "" "")
  4979.           (match_operand 4 "" "")))]
  4980.   ;; operand 2 is stack_size_rtx
  4981.   ;; operand 3 is next_arg_register
  4982.   ""
  4983.   "
  4984. {
  4985.   rtx fn_rtx, nregs_rtx;
  4986.   rtvec vec;
  4987.  
  4988.   if (GET_MODE (operands[1]) != FUNCTION_MODE)
  4989.     abort ();
  4990.  
  4991.   fn_rtx = operands[1];
  4992.  
  4993. #if 0
  4994.   if (operands[3])
  4995.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
  4996.   else
  4997.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  4998. #else
  4999.   nregs_rtx = const0_rtx;
  5000. #endif
  5001.  
  5002.   vec = gen_rtvec (2,
  5003.            gen_rtx (SET, VOIDmode, operands[0],
  5004.                 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
  5005.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
  5006.  
  5007.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
  5008.  
  5009.   DONE;
  5010. }")
  5011.  
  5012. (define_insn "*call_value_address_sp32"
  5013.   [(set (match_operand 0 "" "=rf")
  5014.     (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
  5015.           (match_operand 2 "" "")))
  5016.    (clobber (reg:SI 15))]
  5017.   ;;- Do not use operand 2 for most machines.
  5018.   "! TARGET_PTR64"
  5019.   "*
  5020. {
  5021.   return \"call %a1,%2%#\";
  5022. }"
  5023.   [(set_attr "type" "call")])
  5024.  
  5025. (define_insn "*call_value_symbolic_sp32"
  5026.   [(set (match_operand 0 "" "=rf")
  5027.     (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
  5028.           (match_operand 2 "" "")))
  5029.    (clobber (reg:SI 15))]
  5030.   ;;- Do not use operand 2 for most machines.
  5031.   "! TARGET_PTR64"
  5032.   "*
  5033. {
  5034.   return \"call %a1,%2%#\";
  5035. }"
  5036.   [(set_attr "type" "call")])
  5037.  
  5038. (define_insn "*call_value_address_sp64"
  5039.   [(set (match_operand 0 "" "=rf")
  5040.     (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
  5041.           (match_operand 2 "" "")))
  5042.    (clobber (reg:DI 15))]
  5043.   ;;- Do not use operand 2 for most machines.
  5044.   "TARGET_PTR64"
  5045.   "*
  5046. {
  5047.   return \"call %a1,%2%#\";
  5048. }"
  5049.   [(set_attr "type" "call")])
  5050.  
  5051. (define_insn "*call_value_symbolic_sp64"
  5052.   [(set (match_operand 0 "" "=rf")
  5053.     (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
  5054.           (match_operand 2 "" "")))
  5055.    (clobber (reg:DI 15))]
  5056.   ;;- Do not use operand 2 for most machines.
  5057.   "TARGET_PTR64"
  5058.   "*
  5059. {
  5060.   return \"call %a1,%2%#\";
  5061. }"
  5062.   [(set_attr "type" "call")])
  5063.  
  5064. (define_expand "untyped_call"
  5065.   [(parallel [(call (match_operand 0 "" "")
  5066.             (const_int 0))
  5067.           (match_operand 1 "" "")
  5068.           (match_operand 2 "" "")])]
  5069.   ""
  5070.   "
  5071. {
  5072.   int i;
  5073.  
  5074.   /* Pass constm1 to indicate that it may expect a structure value, but
  5075.      we don't know what size it is.  */
  5076.   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
  5077.  
  5078.   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  5079.     {
  5080.       rtx set = XVECEXP (operands[2], 0, i);
  5081.       emit_move_insn (SET_DEST (set), SET_SRC (set));
  5082.     }
  5083.  
  5084.   /* The optimizer does not know that the call sets the function value
  5085.      registers we stored in the result block.  We avoid problems by
  5086.      claiming that all hard registers are used and clobbered at this
  5087.      point.  */
  5088.   emit_insn (gen_blockage ());
  5089.  
  5090.   DONE;
  5091. }")
  5092.  
  5093. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  5094. ;; all of memory.  This blocks insns from being moved across this point.
  5095.  
  5096. (define_insn "blockage"
  5097.   [(unspec_volatile [(const_int 0)] 0)]
  5098.   ""
  5099.   "")
  5100.  
  5101. ;; Prepare to return any type including a structure value.
  5102.  
  5103. (define_expand "untyped_return"
  5104.   [(match_operand:BLK 0 "memory_operand" "")
  5105.    (match_operand 1 "" "")]
  5106.   ""
  5107.   "
  5108. {
  5109.   rtx valreg1 = gen_rtx (REG, DImode, 24);
  5110.   rtx valreg2 = gen_rtx (REG, TARGET_V9 ? TFmode : DFmode, 32);
  5111.   rtx result = operands[0];
  5112.  
  5113.   if (! TARGET_V9)
  5114.     {
  5115.       rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
  5116.       rtx value = gen_reg_rtx (SImode);
  5117.  
  5118.       /* Fetch the instruction where we will return to and see if it's an unimp
  5119.      instruction (the most significant 10 bits will be zero).  If so,
  5120.      update the return address to skip the unimp instruction.  */
  5121.       emit_move_insn (value,
  5122.               gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
  5123.       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
  5124.       emit_insn (gen_update_return (rtnreg, value));
  5125.     }
  5126.  
  5127.   /* Reload the function value registers.  */
  5128.   emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
  5129.   emit_move_insn (valreg2,
  5130.           change_address (result, TARGET_V9 ? TFmode : DFmode,
  5131.                   plus_constant (XEXP (result, 0), 8)));
  5132.  
  5133.   /* Put USE insns before the return.  */
  5134.   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
  5135.   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
  5136.  
  5137.   /* Construct the return.  */
  5138.   expand_null_return ();
  5139.  
  5140.   DONE;
  5141. }")
  5142.  
  5143. ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
  5144. ;; and parts of the compiler don't want to believe that the add is needed.
  5145.  
  5146. (define_insn "update_return"
  5147.   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
  5148.            (match_operand:SI 1 "register_operand" "r")] 0)]
  5149.   "! TARGET_V9"
  5150.   "cmp %1,0\;be,a .+8\;add %0,4,%0"
  5151.   [(set_attr "type" "multi")])
  5152.  
  5153. (define_insn "return"
  5154.   [(return)]
  5155.   "! TARGET_EPILOGUE"
  5156.   "* return output_return (operands);"
  5157.   [(set_attr "type" "multi")])
  5158.  
  5159. (define_insn "nop"
  5160.   [(const_int 0)]
  5161.   ""
  5162.   "nop")
  5163.  
  5164. (define_expand "indirect_jump"
  5165.   [(set (pc) (match_operand 0 "address_operand" "p"))]
  5166.   ""
  5167.   "")
  5168.  
  5169. (define_insn "*branch_sp32"
  5170.   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
  5171.   "! TARGET_PTR64"
  5172.  "jmp %a0%#"
  5173.  [(set_attr "type" "uncond_branch")])
  5174.  
  5175. (define_insn "*branch_sp64"
  5176.   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
  5177.   "TARGET_PTR64"
  5178.   "jmp %a0%#"
  5179.   [(set_attr "type" "uncond_branch")])
  5180.  
  5181. ;; ??? Doesn't work with -mflat.
  5182. (define_expand "nonlocal_goto"
  5183.   [(match_operand:SI 0 "general_operand" "")
  5184.    (match_operand:SI 1 "general_operand" "")
  5185.    (match_operand:SI 2 "general_operand" "")
  5186.    (match_operand:SI 3 "" "")]
  5187.   ""
  5188.   "
  5189. {
  5190.   /* Trap instruction to flush all the register windows.  */
  5191.   emit_insn (gen_flush_register_windows ());
  5192.   /* Load the fp value for the containing fn into %fp.
  5193.      This is needed because operands[2] refers to %fp.
  5194.      Virtual register instantiation fails if the virtual %fp isn't set from a
  5195.      register.  Thus we must copy operands[0] into a register if it isn't
  5196.      already one.  */
  5197.   if (GET_CODE (operands[0]) != REG)
  5198.     operands[0] = force_reg (Pmode, operands[0]);
  5199.   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
  5200.   /* Find the containing function's current nonlocal goto handler,
  5201.      which will do any cleanups and then jump to the label.  */
  5202.   emit_move_insn (gen_rtx (REG, Pmode, 8), operands[1]);
  5203.   /* Restore %fp from stack pointer value for containing function.
  5204.      The restore insn that follows will move this to %sp,
  5205.      and reload the appropriate value into %fp.  */
  5206.   emit_move_insn (frame_pointer_rtx, operands[2]);
  5207.   /* Put in the static chain register the nonlocal label address.  */
  5208.   emit_move_insn (static_chain_rtx, operands[3]);
  5209.   /* USE of frame_pointer_rtx added for consistency; not clear if
  5210.      really needed.  */
  5211.   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
  5212.   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
  5213.   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
  5214.   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, Pmode, 8)));
  5215.   /* Return, restoring reg window and jumping to goto handler.  */
  5216.   emit_insn (gen_goto_handler_and_restore ());
  5217.   DONE;
  5218. }")
  5219.  
  5220. ;; Special trap insn to flush register windows.
  5221. (define_insn "flush_register_windows"
  5222.   [(unspec_volatile [(const_int 0)] 1)]
  5223.   ""
  5224.   "* return TARGET_V9 ? \"flushw\" : \"ta 3\";"
  5225.   [(set_attr "type" "misc")])
  5226.  
  5227. (define_insn "goto_handler_and_restore"
  5228.   [(unspec_volatile [(const_int 0)] 2)]
  5229.   ""
  5230.   "jmp %%o0+0\;restore"
  5231.   [(set_attr "type" "misc")
  5232.    (set_attr "length" "2")])
  5233.  
  5234. ;; Special pattern for the FLUSH instruction.
  5235.  
  5236. (define_insn "flush"
  5237.   [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)]
  5238.   ""
  5239.   "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
  5240.   [(set_attr "type" "misc")])
  5241.  
  5242. ;; find first set.
  5243.  
  5244. ;; The scan instruction searches from the most significant bit while ffs
  5245. ;; searches from the least significant bit.  The bit index and treatment of
  5246. ;; zero also differ.  It takes at least 7 instructions to get the proper
  5247. ;; result.  Here is an obvious 8 instruction sequence.
  5248.  
  5249. (define_insn "ffssi2"
  5250.   [(set (match_operand:SI 0 "register_operand" "=&r")
  5251.     (ffs:SI (match_operand:SI 1 "register_operand" "r")))
  5252.    (clobber (match_scratch:SI 2 "=&r"))]
  5253.   "TARGET_SPARCLITE"
  5254.   "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0"
  5255.   [(set_attr "type" "multi")
  5256.    (set_attr "length" "8")])
  5257.  
  5258. ;; ??? This should be a define expand, so that the extra instruction have
  5259. ;; a chance of being optimized away.
  5260.  
  5261. (define_insn "ffsdi2"
  5262.   [(set (match_operand:DI 0 "register_operand" "=&r")
  5263.     (ffs:DI (match_operand:DI 1 "register_operand" "r")))
  5264.    (clobber (match_scratch:DI 2 "=&r"))]
  5265.   "TARGET_V9"
  5266.   "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0"
  5267.   [(set_attr "type" "multi")
  5268.    (set_attr "length" "5")])
  5269.  
  5270. ;; Split up troublesome insns for better scheduling.  */
  5271.  
  5272. ;; The following patterns are straightforward.  They can be applied
  5273. ;; either before or after register allocation.
  5274.  
  5275. (define_split
  5276.   [(set (match_operand 0 "splittable_symbolic_memory_operand" "")
  5277.     (match_operand 1 "reg_or_0_operand" ""))
  5278.    (clobber (match_operand:SI 2 "register_operand" ""))]
  5279.   "! flag_pic"
  5280.   [(set (match_dup 2) (high:SI (match_dup 3)))
  5281.    (set (match_dup 4) (match_dup 1))]
  5282.   "
  5283. {
  5284.   operands[3] = XEXP (operands[0], 0);
  5285.   operands[4] = gen_rtx (MEM, GET_MODE (operands[0]),
  5286.              gen_rtx (LO_SUM, SImode, operands[2], operands[3]));
  5287.   MEM_IN_STRUCT_P (operands[4]) = MEM_IN_STRUCT_P (operands[0]);
  5288.   MEM_VOLATILE_P (operands[4]) = MEM_VOLATILE_P (operands[0]);
  5289.   RTX_UNCHANGING_P (operands[4]) = RTX_UNCHANGING_P (operands[0]);
  5290. }")
  5291.  
  5292. (define_split
  5293.   [(set (match_operand 0 "splittable_immediate_memory_operand" "")
  5294.     (match_operand 1 "general_operand" ""))
  5295.    (clobber (match_operand:SI 2 "register_operand" ""))]
  5296.   "flag_pic"
  5297.   [(set (match_dup 3) (match_dup 1))]
  5298.   "
  5299. {
  5300.   rtx addr = legitimize_pic_address (XEXP (operands[0], 0),
  5301.                      GET_MODE (operands[0]),
  5302.                      operands[2]);
  5303.   operands[3] = gen_rtx (MEM, GET_MODE (operands[0]), addr);
  5304.   MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[0]);
  5305.   MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[0]);
  5306.   RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[0]);
  5307. }")
  5308.  
  5309. (define_split
  5310.   [(set (match_operand 0 "register_operand" "")
  5311.     (match_operand 1 "splittable_immediate_memory_operand" ""))]
  5312.   "flag_pic"
  5313.   [(set (match_dup 0) (match_dup 2))]
  5314.   "
  5315. {
  5316.   rtx addr = legitimize_pic_address (XEXP (operands[1], 0),
  5317.                      GET_MODE (operands[1]),
  5318.                      operands[0]);
  5319.   operands[2] = gen_rtx (MEM, GET_MODE (operands[1]), addr);
  5320.   MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
  5321.   MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
  5322.   RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
  5323. }")
  5324.  
  5325. ;; Sign- and Zero-extend operations can have symbolic memory operands.
  5326.  
  5327. (define_split
  5328.   [(set (match_operand 0 "register_operand" "")
  5329.     (match_operator 1 "extend_op" [(match_operand 2 "splittable_immediate_memory_operand" "")]))]
  5330.   "flag_pic"
  5331.   [(set (match_dup 0) (match_op_dup 1 [(match_dup 3)]))]
  5332.   "
  5333. {
  5334.   rtx addr = legitimize_pic_address (XEXP (operands[2], 0),
  5335.                      GET_MODE (operands[2]),
  5336.                      operands[0]);
  5337.   operands[3] = gen_rtx (MEM, GET_MODE (operands[2]), addr);
  5338.   MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[2]);
  5339.   MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[2]);
  5340.   RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[2]);
  5341. }")
  5342.  
  5343. (define_split
  5344.   [(set (match_operand:SI 0 "register_operand" "")
  5345.     (match_operand:SI 1 "immediate_operand" ""))]
  5346.   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
  5347.           || GET_CODE (operands[1]) == CONST
  5348.           || GET_CODE (operands[1]) == LABEL_REF)"
  5349.   [(set (match_dup 0) (high:SI (match_dup 1)))
  5350.    (set (match_dup 0)
  5351.     (lo_sum:SI (match_dup 0) (match_dup 1)))]
  5352.   "")
  5353.  
  5354. ;; LABEL_REFs are not modified by `legitimize_pic_address`
  5355. ;; so do not recurse infinitely in the PIC case.
  5356. (define_split
  5357.   [(set (match_operand:SI 0 "register_operand" "")
  5358.     (match_operand:SI 1 "immediate_operand" ""))]
  5359.   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
  5360.         || GET_CODE (operands[1]) == CONST)"
  5361.   [(set (match_dup 0) (match_dup 1))]
  5362.   "
  5363. {
  5364.   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
  5365. }")
  5366.  
  5367. ;; These split sne/seq insns.  The forms of the resulting insns are 
  5368. ;; somewhat bogus, but they avoid extra patterns and show data dependency.
  5369. ;; Nothing will look at these in detail after splitting has occurred.
  5370.  
  5371. ;; ??? v9 DImode versions are missing because addc and subc use %icc.
  5372.  
  5373. (define_split
  5374.   [(set (match_operand:SI 0 "register_operand" "")
  5375.     (ne:SI (match_operand:SI 1 "register_operand" "")
  5376.            (const_int 0)))
  5377.    (clobber (reg:CC 0))]
  5378.   ""
  5379.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5380.                      (const_int 0)))
  5381.    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
  5382.   "")
  5383.  
  5384. (define_split
  5385.   [(set (match_operand:SI 0 "register_operand" "")
  5386.     (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
  5387.                (const_int 0))))
  5388.    (clobber (reg:CC 0))]
  5389.   ""
  5390.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5391.                      (const_int 0)))
  5392.    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
  5393.   "")
  5394.  
  5395. (define_split
  5396.   [(set (match_operand:SI 0 "register_operand" "")
  5397.     (eq:SI (match_operand:SI 1 "register_operand" "")
  5398.            (const_int 0)))
  5399.    (clobber (reg:CC 0))]
  5400.   ""
  5401.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5402.                      (const_int 0)))
  5403.    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
  5404.   "")
  5405.  
  5406. (define_split
  5407.   [(set (match_operand:SI 0 "register_operand" "")
  5408.     (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
  5409.                (const_int 0))))
  5410.    (clobber (reg:CC 0))]
  5411.   ""
  5412.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5413.                      (const_int 0)))
  5414.    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
  5415.   "")
  5416.  
  5417. (define_split
  5418.   [(set (match_operand:SI 0 "register_operand" "")
  5419.     (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
  5420.             (const_int 0))
  5421.          (match_operand:SI 2 "register_operand" "")))
  5422.    (clobber (reg:CC 0))]
  5423.   ""
  5424.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5425.                      (const_int 0)))
  5426.    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  5427.                    (match_dup 2)))]
  5428.   "")
  5429.  
  5430. (define_split
  5431.   [(set (match_operand:SI 0 "register_operand" "")
  5432.     (minus:SI (match_operand:SI 2 "register_operand" "")
  5433.           (ne:SI (match_operand:SI 1 "register_operand" "")
  5434.              (const_int 0))))
  5435.    (clobber (reg:CC 0))]
  5436.   ""
  5437.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5438.                      (const_int 0)))
  5439.    (set (match_dup 0) (minus:SI (match_dup 2)
  5440.                 (ltu:SI (reg:CC 0) (const_int 0))))]
  5441.   "")
  5442.  
  5443. (define_split
  5444.   [(set (match_operand:SI 0 "register_operand" "")
  5445.     (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
  5446.             (const_int 0))
  5447.          (match_operand:SI 2 "register_operand" "")))
  5448.    (clobber (reg:CC 0))]
  5449.   ""
  5450.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5451.                      (const_int 0)))
  5452.    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
  5453.                    (match_dup 2)))]
  5454.   "")
  5455.  
  5456. (define_split
  5457.   [(set (match_operand:SI 0 "register_operand" "")
  5458.     (minus:SI (match_operand:SI 2 "register_operand" "")
  5459.           (eq:SI (match_operand:SI 1 "register_operand" "")
  5460.              (const_int 0))))
  5461.    (clobber (reg:CC 0))]
  5462.   ""
  5463.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  5464.                      (const_int 0)))
  5465.    (set (match_dup 0) (minus:SI (match_dup 2)
  5466.                 (geu:SI (reg:CC 0) (const_int 0))))]
  5467.   "")
  5468.  
  5469. ;; Peepholes go at the end.
  5470.  
  5471. ;; Optimize consecutive loads or stores into ldd and std when possible.
  5472. ;; The conditions in which we do this are very restricted and are 
  5473. ;; explained in the code for {registers,memory}_ok_for_ldd functions.
  5474.  
  5475. (define_peephole
  5476.   [(set (match_operand:SI 0 "register_operand" "=rf")
  5477.         (match_operand:SI 1 "memory_operand" ""))
  5478.    (set (match_operand:SI 2 "register_operand" "=rf")
  5479.         (match_operand:SI 3 "memory_operand" ""))]
  5480.   "! TARGET_V9
  5481.    && registers_ok_for_ldd_peep (operands[0], operands[2]) 
  5482.    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
  5483.    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
  5484.   "ldd %1,%0")
  5485.  
  5486. (define_peephole
  5487.   [(set (match_operand:SI 0 "memory_operand" "")
  5488.         (match_operand:SI 1 "register_operand" "rf"))
  5489.    (set (match_operand:SI 2 "memory_operand" "")
  5490.         (match_operand:SI 3 "register_operand" "rf"))]
  5491.   "! TARGET_V9
  5492.    && registers_ok_for_ldd_peep (operands[1], operands[3]) 
  5493.    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
  5494.    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
  5495.   "std %1,%0")
  5496.  
  5497. (define_peephole
  5498.   [(set (match_operand:SF 0 "register_operand" "=fr")
  5499.         (match_operand:SF 1 "memory_operand" ""))
  5500.    (set (match_operand:SF 2 "register_operand" "=fr")
  5501.         (match_operand:SF 3 "memory_operand" ""))]
  5502.   "! TARGET_V9
  5503.    && registers_ok_for_ldd_peep (operands[0], operands[2]) 
  5504.    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
  5505.    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
  5506.   "ldd %1,%0")
  5507.  
  5508. (define_peephole
  5509.   [(set (match_operand:SF 0 "memory_operand" "")
  5510.         (match_operand:SF 1 "register_operand" "fr"))
  5511.    (set (match_operand:SF 2 "memory_operand" "")
  5512.         (match_operand:SF 3 "register_operand" "fr"))]
  5513.   "! TARGET_V9
  5514.    && registers_ok_for_ldd_peep (operands[1], operands[3]) 
  5515.    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
  5516.    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
  5517.   "std %1,%0")
  5518.  
  5519. (define_peephole
  5520.   [(set (match_operand:SI 0 "register_operand" "=rf")
  5521.         (match_operand:SI 1 "memory_operand" ""))
  5522.    (set (match_operand:SI 2 "register_operand" "=rf")
  5523.         (match_operand:SI 3 "memory_operand" ""))]
  5524.   "! TARGET_V9
  5525.    && registers_ok_for_ldd_peep (operands[2], operands[0]) 
  5526.    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
  5527.    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
  5528.   "ldd %3,%2")
  5529.  
  5530. (define_peephole
  5531.   [(set (match_operand:SI 0 "memory_operand" "")
  5532.         (match_operand:SI 1 "register_operand" "rf"))
  5533.    (set (match_operand:SI 2 "memory_operand" "")
  5534.         (match_operand:SI 3 "register_operand" "rf"))]
  5535.   "! TARGET_V9
  5536.    && registers_ok_for_ldd_peep (operands[3], operands[1]) 
  5537.    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
  5538.    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
  5539.   "std %3,%2")
  5540.  
  5541. (define_peephole
  5542.   [(set (match_operand:SF 0 "register_operand" "=fr")
  5543.         (match_operand:SF 1 "memory_operand" ""))
  5544.    (set (match_operand:SF 2 "register_operand" "=fr")
  5545.         (match_operand:SF 3 "memory_operand" ""))]
  5546.   "! TARGET_V9
  5547.    && registers_ok_for_ldd_peep (operands[2], operands[0]) 
  5548.    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
  5549.    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
  5550.   "ldd %3,%2")
  5551.  
  5552. (define_peephole
  5553.   [(set (match_operand:SF 0 "memory_operand" "")
  5554.         (match_operand:SF 1 "register_operand" "fr"))
  5555.    (set (match_operand:SF 2 "memory_operand" "")
  5556.         (match_operand:SF 3 "register_operand" "fr"))]
  5557.   "! TARGET_V9
  5558.    && registers_ok_for_ldd_peep (operands[3], operands[1]) 
  5559.    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
  5560.    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
  5561.   "std %3,%2")
  5562.  
  5563. ;; Optimize the case of following a reg-reg move with a test
  5564. ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
  5565. ;; This can result from a float to fix conversion.
  5566.  
  5567. (define_peephole
  5568.   [(set (match_operand:SI 0 "register_operand" "=r")
  5569.     (match_operand:SI 1 "register_operand" "r"))
  5570.    (set (reg:CC 0)
  5571.     (compare:CC (match_operand:SI 2 "register_operand" "r")
  5572.             (const_int 0)))]
  5573.   "(rtx_equal_p (operands[2], operands[0])
  5574.     || rtx_equal_p (operands[2], operands[1]))
  5575.    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
  5576.   "orcc %1,%%g0,%0")
  5577.  
  5578. (define_peephole
  5579.   [(set (match_operand:DI 0 "register_operand" "=r")
  5580.     (match_operand:DI 1 "register_operand" "r"))
  5581.    (set (reg:CCX 0)
  5582.     (compare:CCX (match_operand:DI 2 "register_operand" "r")
  5583.             (const_int 0)))]
  5584.   "TARGET_V9
  5585.    && (rtx_equal_p (operands[2], operands[0])
  5586.        || rtx_equal_p (operands[2], operands[1]))
  5587.    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
  5588.   "orcc %1,%%g0,%0")
  5589.  
  5590. ;; Do {sign,zero}-extended compares somewhat more efficiently.
  5591. ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
  5592. ;;     eventually have some impact here?
  5593.  
  5594. (define_peephole
  5595.   [(set (match_operand:HI 0 "register_operand" "")
  5596.     (match_operand:HI 1 "memory_operand" ""))
  5597.    (set (match_operand:SI 2 "register_operand" "")
  5598.     (sign_extend:SI (match_dup 0)))
  5599.    (set (reg:CC 0)
  5600.     (compare:CC (match_dup 2)
  5601.             (const_int 0)))]
  5602.   ""
  5603.   "ldsh %1,%0\;orcc %0,%%g0,%2")
  5604.  
  5605. (define_peephole
  5606.   [(set (match_operand:HI 0 "register_operand" "")
  5607.     (match_operand:HI 1 "memory_operand" ""))
  5608.    (set (match_operand:DI 2 "register_operand" "")
  5609.     (sign_extend:DI (match_dup 0)))
  5610.    (set (reg:CCX 0)
  5611.     (compare:CCX (match_dup 2)
  5612.              (const_int 0)))]
  5613.   "TARGET_V9"
  5614.   "ldsh %1,%0\;orcc %0,%%g0,%2")
  5615.  
  5616. (define_peephole
  5617.   [(set (match_operand:QI 0 "register_operand" "")
  5618.     (match_operand:QI 1 "memory_operand" ""))
  5619.    (set (match_operand:SI 2 "register_operand" "")
  5620.     (sign_extend:SI (match_dup 0)))
  5621.    (set (reg:CC 0)
  5622.     (compare:CC (match_dup 2)
  5623.             (const_int 0)))]
  5624.   ""
  5625.   "ldsb %1,%0\;orcc %0,%%g0,%2")
  5626.  
  5627. (define_peephole
  5628.   [(set (match_operand:QI 0 "register_operand" "")
  5629.     (match_operand:QI 1 "memory_operand" ""))
  5630.    (set (match_operand:DI 2 "register_operand" "")
  5631.     (sign_extend:DI (match_dup 0)))
  5632.    (set (reg:CCX 0)
  5633.     (compare:CCX (match_dup 2)
  5634.              (const_int 0)))]
  5635.   "TARGET_V9"
  5636.   "ldsb %1,%0\;orcc %0,%%g0,%2")
  5637.  
  5638. ;; Floating-point move peepholes
  5639. ;; ??? v9: Do we want similar ones?
  5640.  
  5641. (define_peephole
  5642.   [(set (match_operand:SI 0 "register_operand" "=r")
  5643.     (lo_sum:SI (match_dup 0)
  5644.            (match_operand:SI 1 "immediate_operand" "i")))
  5645.    (set (match_operand:DF 2 "register_operand" "=er")
  5646.     (mem:DF (match_dup 0)))]
  5647.   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
  5648.   "*
  5649. {
  5650.   /* Go by way of output_move_double in case the register in operand 2
  5651.      is not properly aligned for ldd.  */
  5652.   operands[1] = gen_rtx (MEM, DFmode,
  5653.              gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
  5654.   operands[0] = operands[2];
  5655.   return output_move_double (operands);
  5656. }")
  5657.  
  5658. (define_peephole
  5659.   [(set (match_operand:SI 0 "register_operand" "=r")
  5660.     (lo_sum:SI (match_dup 0)
  5661.            (match_operand:SI 1 "immediate_operand" "i")))
  5662.    (set (match_operand:SF 2 "register_operand" "=fr")
  5663.     (mem:SF (match_dup 0)))]
  5664.   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
  5665.   "ld [%0+%%lo(%a1)],%2")
  5666.  
  5667. ;; Return peepholes.  First the "normal" ones
  5668.  
  5669. ;; ??? There are QImode, HImode, and SImode versions of this pattern.
  5670. ;; It might be possible to write one more general pattern instead of three.
  5671.  
  5672. (define_insn "*return_qi"
  5673.   [(set (match_operand:QI 0 "restore_operand" "")
  5674.     (match_operand:QI 1 "arith_operand" "rI"))
  5675.    (return)]
  5676.   "! TARGET_EPILOGUE"
  5677.   "*
  5678. {
  5679.   if (! TARGET_V9 && current_function_returns_struct)
  5680.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  5681.   else
  5682.     return \"ret\;restore %%g0,%1,%Y0\";
  5683. }"
  5684.   [(set_attr "type" "multi")])
  5685.  
  5686. (define_insn "*return_hi"
  5687.   [(set (match_operand:HI 0 "restore_operand" "")
  5688.     (match_operand:HI 1 "arith_operand" "rI"))
  5689.    (return)]
  5690.   "! TARGET_EPILOGUE"
  5691.   "*
  5692. {
  5693.   if (! TARGET_V9 && current_function_returns_struct)
  5694.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  5695.   else
  5696.     return \"ret\;restore %%g0,%1,%Y0\";
  5697. }"
  5698.   [(set_attr "type" "multi")])
  5699.  
  5700. (define_insn "*return_si"
  5701.   [(set (match_operand:SI 0 "restore_operand" "")
  5702.     (match_operand:SI 1 "arith_operand" "rI"))
  5703.    (return)]
  5704.   "! TARGET_EPILOGUE"
  5705.   "*
  5706. {
  5707.   if (! TARGET_V9 && current_function_returns_struct)
  5708.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  5709.   else
  5710.     return \"ret\;restore %%g0,%1,%Y0\";
  5711. }"
  5712.   [(set_attr "type" "multi")])
  5713.  
  5714. ;; The following pattern is only generated by delayed-branch scheduling,
  5715. ;; when the insn winds up in the epilogue.  This can only happen when
  5716. ;; ! TARGET_FPU because otherwise fp return values are in %f0.
  5717. (define_insn "*return_sf_no_fpu"
  5718.   [(set (match_operand:SF 0 "restore_operand" "r")
  5719.     (match_operand:SF 1 "register_operand" "r"))
  5720.    (return)]
  5721.   "! TARGET_FPU && ! TARGET_EPILOGUE"
  5722.   "*
  5723. {
  5724.   if (! TARGET_V9 && current_function_returns_struct)
  5725.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  5726.   else
  5727.     return \"ret\;restore %%g0,%1,%Y0\";
  5728. }"
  5729.   [(set_attr "type" "multi")])
  5730.  
  5731. (define_insn "*return_addsi"
  5732.   [(set (match_operand:SI 0 "restore_operand" "")
  5733.     (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  5734.          (match_operand:SI 2 "arith_operand" "rI")))
  5735.    (return)]
  5736.   "! TARGET_EPILOGUE"
  5737.   "*
  5738. {
  5739.   if (! TARGET_V9 && current_function_returns_struct)
  5740.     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
  5741.   else
  5742.     return \"ret\;restore %r1,%2,%Y0\";
  5743. }"
  5744.   [(set_attr "type" "multi")])
  5745.  
  5746. (define_insn "*return_di"
  5747.   [(set (match_operand:DI 0 "restore_operand" "")
  5748.     (match_operand:DI 1 "arith_double_operand" "rHI"))
  5749.    (return)]
  5750.   "TARGET_V9 && ! TARGET_EPILOGUE"
  5751.   "ret\;restore %%g0,%1,%Y0"
  5752.   [(set_attr "type" "multi")])
  5753.  
  5754. (define_insn "*return_adddi"
  5755.   [(set (match_operand:DI 0 "restore_operand" "")
  5756.     (plus:DI (match_operand:DI 1 "arith_operand" "%r")
  5757.          (match_operand:DI 2 "arith_double_operand" "rHI")))
  5758.    (return)]
  5759.   "TARGET_V9 && ! TARGET_EPILOGUE"
  5760.   "ret\;restore %r1,%2,%Y0"
  5761.   [(set_attr "type" "multi")])
  5762.  
  5763. ;; Turned off because it should never match (subtracting a constant
  5764. ;; is turned into addition) and because it would do the wrong thing
  5765. ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
  5766. ;;(define_insn "*minus_const"
  5767. ;;  [(set (match_operand:SI 0 "restore_operand" "")
  5768. ;;    (minus:SI (match_operand:SI 1 "register_operand" "r")
  5769. ;;          (match_operand:SI 2 "small_int" "I")))
  5770. ;;   (return)]
  5771. ;;  "! TARGET_EPILOGUE"
  5772. ;;  "ret\;restore %1,-(%2),%Y0"
  5773. ;;  [(set_attr "type" "multi")])
  5774.  
  5775. ;; The following pattern is only generated by delayed-branch scheduling,
  5776. ;; when the insn winds up in the epilogue.
  5777. (define_insn "*return_sf"
  5778.   [(set (reg:SF 32)
  5779.     (match_operand:SF 0 "register_operand" "f"))
  5780.    (return)]
  5781.   "! TARGET_EPILOGUE"
  5782.   "ret\;fmovs %0,%%f0"
  5783.   [(set_attr "type" "multi")])
  5784.  
  5785. ;; Now peepholes to do a call followed by a jump.
  5786.  
  5787. (define_peephole
  5788.   [(parallel [(set (match_operand 0 "" "")
  5789.            (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
  5790.              (match_operand 2 "" "")))
  5791.           (clobber (reg:SI 15))])
  5792.    (set (pc) (label_ref (match_operand 3 "" "")))]
  5793.   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
  5794.   "*
  5795. {
  5796.   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
  5797. }")
  5798.  
  5799. (define_peephole
  5800.   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
  5801.             (match_operand 1 "" ""))
  5802.           (clobber (reg:SI 15))])
  5803.    (set (pc) (label_ref (match_operand 2 "" "")))]
  5804.   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
  5805.   "*
  5806. {
  5807.   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
  5808. }")
  5809.  
  5810. (define_peephole
  5811.   [(parallel [(set (match_operand 0 "" "")
  5812.            (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
  5813.              (match_operand 2 "" "")))
  5814.           (clobber (reg:DI 15))])
  5815.    (set (pc) (label_ref (match_operand 3 "" "")))]
  5816.   "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
  5817.   "*
  5818. {
  5819.   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
  5820. }")
  5821.  
  5822. (define_peephole
  5823.   [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
  5824.             (match_operand 1 "" ""))
  5825.           (clobber (reg:DI 15))])
  5826.    (set (pc) (label_ref (match_operand 2 "" "")))]
  5827.   "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
  5828.   "*
  5829. {
  5830.   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
  5831. }")
  5832.  
  5833. ;; Other miscellaneous peepholes.
  5834.  
  5835. (define_peephole
  5836.   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
  5837.            (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
  5838.                  (reg:SI 0)))
  5839.           (clobber (reg:CC 0))])
  5840.    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
  5841.   ""
  5842.   "subxcc %r1,0,%0")
  5843.